3

我再问this question,因为代码和示例是错误的(它实际上在所示情况下工作)。Rails的ActiveRecord:跳过验证的协会

鉴于这些机型:

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) 

但是,如果我们从数据库中检索无效的书籍,并在作者指定的关联,我们不允许保存作者:

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

这是错误:

ActiveRecord::RecordInvalid: Validation failed: Books is invalid

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

请注意,在作者说has_many :books, :validate => false没有帮助:关联被默默丢弃与作者保存。

回答

11

试一下

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 

据我了解,在验证=>虚假只允许你保存作者没有由无效的书被停止,但为了节省您需要一个有效的书,你的关联将更改author_id密钥。 您无法更改rails内部结构,但您仍然可以通过保存作者而无需验证,然后更新每本书并立即强制保存(使用save(false))来欺骗它。

当然,这个代码可以在很多方面得到增强,因为可能没有必要每次开始时都保存所有的图书,但是你明白了。

+0

谢谢!你的代码有效。我忽略了关联正在更新外键(因此模型需要有效)。 – 2010-12-16 00:51:29