1

默認情況下,Rails3是否始終針對所有模型運​​行validates_associatedActiveModel:關聯模型失效時禁用驗證失敗

在一個簡單的設置像這樣

class Post < ActiveRecord::Base 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :post 

    def validate 
     errors.add_to_base("its always invalid") 
    end 
end 

發新帖附加註釋失敗,因爲評論是無效的。

a = Post.new 
a.comments << Comment.new 
a.errors 
    => {:comments=>["is invalid"]} 

如果validates_associated始終運行,那麼爲什麼它有(改變:message?),我如何把它關掉?我試過validates_associated :comments, :unless => proc{true},但它什麼也沒做。

我只是想要一個模型來保存,嘗試保存每個關聯的記錄,如果每個都是有效的,但如果關聯模型無效則不會自行失效。


編輯:這是更接近我想要做

# t.string :name 
class Game < ActiveRecord::Base 
    has_one :wikipedia_paragraph 
    has_one :ign_rating 

    def name=(_name) 
     ret = super 
     self.build_wikipedia_paragraph 
     self.build_ign_rating 
     ret 
    end 
end 


# t.text :paragraph 
class WikipediaParagraph < ActiveRecord::Base 
    belongs_to :game 

    validates_presence_of :paragraph 

    def game=(_game) 
     ret = super 
     self.paragraph = Wikipedia.find(self.game.name) 
     ret 
    end 
end 

class IgnRating.. 

有跡象表明,遵循相同的結構遊戲,像書籍,電影更多的車型。如果WikipediaParagraph.paragraph == nil則遊戲未通過驗證。我寧願如果遊戲保存和WikipediaParagraph沒有,但has_one :wikipedia_paragraph, :validate => false使兩個保存,沒有它既不保存。

我希望的東西比使用

self.build_wikipedia_paragraph 
self.wikipedia_paragraph = nil unless self.wikipedia_paragraph.valid? 

爲每has_one/many更優雅,但現在我意識到它可能是不可能的。

回答

0

您的驗證強制執行應用程序的業務邏輯。如果您始終希望Post對象保存,則無論相關注釋的狀態如何,您都可以獨立保存帖子和註釋。這將允許你遍歷的意見收集,並嘗試每節省,如果繼續出現錯誤

post = Post.new 
post.valid? # true 

comments.each do |comment| 
    comment.save # some will some wont 
end 

我知道這並不完全解決您的問題,因爲你描述它,但它可能會考慮爲什麼要禁用關聯驗證。在has_many調用中,validate => false的問題是,它將始終保存,而不進行驗證,這可能不是您想要的。

有更正統的方法來解決這個問題,同時保持驗證存在?

3

查閱文檔http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many。它顯示保存父對象時默認驗證has_many關聯。你可以將它設置爲false,像這樣:

class Post < ActiveRecord::Base 
    has_many :comments, :validate => false 
end 

我想validates_associated可以派上用場,如果你不驗證默認關聯,並希望自己處理。整個情況有點混亂,所以我希望這有助於。