【问题标题】:Rails ActiveRecord: Skip validations for associationsRails ActiveRecord:跳过关联验证
【发布时间】:2011-05-22 14:07:01
【问题描述】:

我重新询问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

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

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

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

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

这是错误:

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

我们如何跳过相关 Book 模型的验证而不跳过 Author 的验证?

请注意,在 Author 中说 has_many :books, :validate =&gt; false 并没有帮助:关联被默默地丢弃,而 Author 被保存。

【问题讨论】:

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


    【解决方案1】:

    试试看

    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 => false 仅允许您保存作者而不会被无效书籍阻止,但要保存关联,您需要一本有效的书籍,因为您将更改 author_id 键。 您无法更改 Rails 内部结构,但您仍然可以通过在不验证的情况下保存作者,然后立即更新每本书并强制保存(使用 save(false))来欺骗它。

    当然,此代码可以通过多种方式进行增强,因为可能没有必要每次都保存所有书籍以便开始,但你明白了。

    【讨论】:

    • 谢谢!您的代码有效。我忽略了关联正在更新外键(因此模型需要有效)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多