Rails ActiveRecord:跳过关联的验证

时间:2010-12-09 00:54:19

标签: ruby-on-rails validation activerecord ruby-on-rails-3 associations

我正在重新询问this question,因为代码和示例是错误的(它实际上适用于所示的情况)。

鉴于这些模型:

class Author < ActiveRecord::Base
  has_many :books
  validates_presence_of :email
end

class Book < ActiveRecord::Base
  belongs_to :author
  validates_presence_of :title
end

我们可以在创建图书时跳过验证:

b = Book.new
b.save(:validate => false)

但是如果我们从数据库中检索无效的Book并将其分配给Author中的关联,我们就不允许保存作者:

a = Author.new
a.email = "foo"
a.books = Book.all
a.save!

这是错误:

  

ActiveRecord :: RecordInvalid:验证失败:图书无效

我们如何跳过相关图书模型的验证而不为作者跳过它们?

请注意,在作者中说has_many :books, :validate => false没有帮助:在保存作者的情况下,会无声地放弃关联。

1 个答案:

答案 0 :(得分:12)

试试

class Author < ActiveRecord::Base
  has_many :books, :validate => false
  validates_presence_of :email
  after_save :save_invalid_books

  def save_invalid_books
    books.each do |b|
      b.save(false)
    end
  end
end

据我了解,validate =&gt; false仅允许您保存作者而不会被无效的书籍停止,但是为了保存关联,您需要一本有效的书籍,因为您将更改author_id键。 您无法更改rails内部,但您仍然可以通过保存作者而不进行验证来欺骗它,然后更新每本书并在之后强制保存(使用save(false))。

当然,这段代码可以通过多种方式得到增强,因为可能没有必要每次都保存所有书籍,但是你明白了。