简体   繁体   English

Ruby on Rails具有ActiveRecord错误处理的怪异行为

[英]Ruby on Rails bizarre behavior with ActiveRecord error handling

Can anyone explain why this happens? 谁能解释为什么会这样?

mybox:$ ruby script/console
Loading development environment (Rails 2.3.5)
>> foo = Foo.new
=> #<Foo id: nil, customer_id: nil, created_at: nil, updated_at: nil>
>> bar = Bar.new
=> #<Bar id: nil, bundle_id: nil, alias: nil, real: nil, active: true, list_type: 0, body_record_active: false, created_at: nil, updated_at: nil>
>> bar.save
=> false
>> bar.errors.each_full { |msg| puts msg }
Real can't be blank
Real You must supply a valid email
=> ["Real can't be blank", "Real You must supply a valid email"]

So far that is perfect, that is what i want the error message to read. 到目前为止,这是完美的,这就是我希望读取的错误消息。 Now for more: 现在更多:

>> foo.bars << bar
=> [#<Bar id: nil, bundle_id: nil, alias: nil, real: nil, active: true, list_type: 0, body_record_active: false, created_at: nil, updated_at: nil>]
>> foo.save
=> false
>> foo.errors.to_xml
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>\n  <error>Bars is invalid</error>\n</errors>\n"

That is what I can't figure out. 那是我不知道的。 Why am I getting Bars is invalid versus the error messages displayed above, ["Real can't be blank", "Real you must supply a valid email"] etc. 与上面显示的错误消息相比,[为什么我不能得到Bars无效],[“ Real不能为空”,“ Real您必须提供有效的电子邮件”]等。

My controller simply has a respond_to method with the following in it: 我的控制器仅具有一个respond_to方法,其中包含以下内容:

 format.xml  { render :xml => @foo.errors, :status => :unprocessable_entity }

How do I have this output the real error messages so the user has some insight into what they did wrong? 我该如何输出真正的错误消息,以便用户对自己的错误做些了解? How do I write my render method in my controller to show all of the appropriate error messages? 如何在控制器中编写render方法以显示所有适当的错误消息?

I think you are using 我想你在用

validates_associated :bar in your foo.rb MODEL validates_associated:bar在您的foo.rb模型中

so it only giving "Bars is invalid" 所以它只给出“酒吧是无效的”

to check the error messages for bars either you have to do following in your 检查酒吧的错误消息,您必须在您的以下操作

VIEW 视图

<%= error_messages_for :foo, :bar %>

Controller 控制者

foo.bar.errors.to_xml foo.bar.errors.to_xml

& to skip "bar is invalid" message put following method in foo.rb &跳过“ bar is invalid”消息,将以下方法放在foo.rb中

  def after_validation
    # Skip errors that won't be useful to the end user
    filtered_errors = self.errors.reject{ |err| %w{ bar }.include?(err.first) }
    self.errors.clear
    filtered_errors.each { |err| self.errors.add(*err) }
  end

It's because the errors for bar are stored in the bar object. 这是因为bar的错误存储在bar对象中。 To get these errors you have to do something like this: 要获取这些错误,您必须执行以下操作:

foo.bar.each do |bar|
  bar.errors.each_full { |msg| puts msg }
end

It's all convoluted to me, but I haven't figured out the best way to get all the errors in one list (besides handling it my self). 这一切对我来说都是令人费解的,但是我还没有找到将所有错误汇总到一个列表中的最佳方法(除了自己处理之外)。 I understand the reasoning behind it (as each object should only know about it's own errors). 我了解其背后的原因(因为每个对象应该只知道它自己的错误)。 What I usually do is extent ActiveRecord::Errors and create a new each_full_with_associations function that returns them all. 我通常要做的是each_full_with_associations ActiveRecord::Errors并创建一个新的each_full_with_associations函数,将其全部返回。

It all makes sense when you see it on a form with nested fields. 当您在带有嵌套字段的表单上看到它时,这一切都是有意义的。 In that case the errors are shown properly and all is good. 在这种情况下,错误会正确显示,并且一切正常。

We used to overwrite an errors method in particular model, if we needed errors of child objects too, smth like that 我们曾经覆盖特定模型中的errors方法,如果我们也需要子对象的错误,像这样

class Foo < ActiveRecord::Base

  alias :errors_without_children :errors

  def errors
    self.bars.each do |i|
      i.errors.each_full do |msg|
        errors_without_children.add_to_base msg
      end
    end
    errors_without_children
  end

end

You can still optimise it more. 您仍然可以对其进行更多优化。 But this one already adds all bars objects' error messages to foo. 但这已经将所有bar对象的错误消息添加到foo。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM