ActiveModel:当关联模型失败时禁用失败验证

发布于 2024-11-19 16:29:55 字数 1669 浏览 2 评论 0原文

默认情况下,Rails3 是否始终针对所有模型运​​行 validates_linked

在这样的简单设置中,

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_linked 始终运行,那么为什么它会在那里(更改 :message?)以及如何将其关闭?我已经尝试过 validates_linked :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 更优雅的东西,但现在我意识到这可能是不可能的。

Does Rails3 always run validates_associated against all models by default?

In a simple setup like this

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 new post with an attached comment fails because the comment is invalid.

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

If validates_associated always runs, then why is it there (to change :message?) and how do I turn it off? I have tried validates_associated :comments, :unless => proc{true} but it doesn't do anything.

I simply want a model to save, try to save each associated record if each is valid, but not fail itself if an associated model is invalid.


EDIT: This is closer to what I'm trying to do

# 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..

There are more models that follow the same structure as Game, like Book, Movie. If WikipediaParagraph.paragraph == nil then Game fails validation. I would prefer if Game saved and WikipediaParagraph didn't, but has_one :wikipedia_paragraph, :validate => false makes both save, without it neither save.

I was hoping for something more elegant than using

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

for every has_one/many but now I realize its probably not possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

那小子欠揍 2024-11-26 16:29:55

查看文档 http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many 。它表明,保存父对象时,默认情况下会验证 has_many 关联。您可以将其设置为 false,如下所示:

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

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

Check out the documentation http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many. It shows that a has_many association is validated by default when the parent object is saved. You can set it to false like this:

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

I suppose validates_associated could come in handy if you aren't validating an association by default and wanted to handle it yourself. The whole situation is a bit confusing, so I hope that this helps.

喜爱皱眉﹌ 2024-11-26 16:29:55

您的验证强制执行应用程序的业务逻辑。如果您始终希望保存 Post 对象,无论关联评论的状态如何,您可以单独保存帖子和评论。这将允许您迭代一组评论,并尝试保存每个评论,如果出现错误则继续

post = Post.new
post.valid? # true

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

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

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

Your validations enforce the business logic of your application. If you always want the Post object to save, regardless of the state of the associated comments, you can save posts, and comments independently. This would allow you to iterate over a collection of comments, and try to save each on, continuing if there is an error

post = Post.new
post.valid? # true

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

I know this doesn't exactly fix your issue as you have describe it, but it may be good to think about why you want to disable validations on an association. The problem with :validate => false on the has_many call is that it will always save without validation, which may not be what you intend.

Is there a more orthodox way to solve this issue while keeping validations present?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文