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可以派上用场,如果你不验证默认关联,并希望自己处理。整个情况有点混乱,所以我希望这有助于。