ActiveModel:当关联模型失败时禁用失败验证
默认情况下,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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查看文档 http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many 。它表明,保存父对象时,默认情况下会验证 has_many 关联。您可以将其设置为 false,如下所示:
我想如果您默认情况下不验证关联并且想要自己处理它,那么
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:
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.您的验证强制执行应用程序的业务逻辑。如果您始终希望保存 Post 对象,无论关联评论的状态如何,您可以单独保存帖子和评论。这将允许您迭代一组评论,并尝试保存每个评论,如果出现错误则继续
我知道这并不能完全解决您所描述的问题,但考虑一下原因可能会很好您想要禁用关联验证。 :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
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?