繁体   English   中英

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

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

谁能解释为什么会这样?

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"]

到目前为止,这是完美的,这就是我希望读取的错误消息。 现在更多:

>> 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"

那是我不知道的。 与上面显示的错误消息相比,[为什么我不能得到Bars无效],[“ Real不能为空”,“ Real您必须提供有效的电子邮件”]等。

我的控制器仅具有一个respond_to方法,其中包含以下内容:

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

我该如何输出真正的错误消息,以便用户对自己的错误做些了解? 如何在控制器中编写render方法以显示所有适当的错误消息?

我想你在用

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

所以它只给出“酒吧是无效的”

检查酒吧的错误消息,您必须在您的以下操作

视图

<%= error_messages_for :foo, :bar %>

控制者

foo.bar.errors.to_xml

&跳过“ 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

这是因为bar的错误存储在bar对象中。 要获取这些错误,您必须执行以下操作:

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

这一切对我来说都是令人费解的,但是我还没有找到将所有错误汇总到一个列表中的最佳方法(除了自己处理之外)。 我了解其背后的原因(因为每个对象应该只知道它自己的错误)。 我通常要做的是each_full_with_associations ActiveRecord::Errors并创建一个新的each_full_with_associations函数,将其全部返回。

当您在带有嵌套字段的表单上看到它时,这一切都是有意义的。 在这种情况下,错误会正确显示,并且一切正常。

我们曾经覆盖特定模型中的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

您仍然可以对其进行更多优化。 但这已经将所有bar对象的错误消息添加到foo。

暂无
暂无

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

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