【问题标题】:ActiveModel: Disable failing validation when associated models failActiveModel:关联模型失败时禁用失败验证
【发布时间】:2011-10-04 19:45:00
【问题描述】:

默认情况下 Rails3 是否总是针对所有模型运​​行validates_associated

在这样的简单设置中

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 =&gt; 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..

还有更多模型遵循与 Game 相同的结构,例如 Book、Movie。如果 WikipediaParagraph.paragraph == nil 则 Game 验证失败。我希望游戏保存而 WikipediaParagraph 没有保存,但has_one :wikipedia_paragraph, :validate =&gt; false 会同时保存,没有它则不会保存。

我希望有比使用更优雅的东西

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

对于每个has_one/many,但现在我意识到这可能是不可能的。

【问题讨论】:

    标签: ruby-on-rails validation activerecord activemodel validates-associated


    【解决方案1】:

    查看文档http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many。它表明在保存父对象时默认验证 has_many 关联。您可以像这样将其设置为 false:

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

    我想validates_associated 可能会派上用场,如果您不默认验证关联并希望自己处理它。整个情况有点混乱,所以我希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      您的验证会强制执行应用程序的业务逻辑。如果您总是希望 Post 对象保存,无论关联的 cmets 的状态如何,您都可以单独保存帖子和 cmets。这将允许您遍历 cmet 的集合,并尝试保存每个,如果有错误则继续

      post = Post.new
      post.valid? # true
      
      comments.each do |comment|
        comment.save # some will some wont
      end
      

      我知道这并不能完全解决您所描述的问题,但最好考虑一下您为什么要禁用关联验证。 has_many 调用中 :validate => false 的问题在于,它总是会在没有验证的情况下保存,这可能不是您想要的。

      有没有更正统的方法来解决这个问题,同时保持验证存在?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多