【问题标题】:Which approach to use for validating presence of a belongs_to association?使用哪种方法来验证 belongs_to 关联的存在?
【发布时间】:2016-01-27 16:18:31
【问题描述】:

给定

class Post
  has_many :comments
end

class Comment
  belongs_to :post
end

如果我想验证评论总是有帖子,我应该使用

class Comment
  belongs_to :post
  validates :post, presence: true
end

class Comment
  belongs_to :post
  validates :post_id, presence: true
end

?

Rails guides 建议使用 validates :post, presence: true 方法,表示:

如果您想确保存在关联,您需要 测试关联对象本身是否存在,而不是 用于映射关联的外键。

我可以看到两者之间的一个区别是,如果你这样做了

post = Post.new
comment = Comment.new
comment.post = post
comment.save

如果基于post_id,则验证失败,但如果基于post,则验证成功。后者对我来说更有意义。

但是,我有时会在现实生活中看到人们使用post_id 方法。他们只是使用了“错误”的方法,还是有我不知道的理由?

Rails Style Guide 没有与此主题相关的任何内容。

Rails ActiveRecord:: Proper way for validating presence on associations? 的问题似乎是在询问如何使用post_id 方法让项目工作,但似乎没有解释为什么要使用这种方法。

Rails 4: Difference between validates presence on id or association 是关于验证的,但只是描述了两种方法的不同效果,而不是说明为什么应该使用post_id

Rails - Validate Presence Of Association? 的问题无关紧要 - 它是在讨论验证帖子是否至少包含一条评论,这与我所问的要求不同。

【问题讨论】:

    标签: ruby-on-rails validation rails-activerecord


    【解决方案1】:

    我不认为一个案例适合所有场景。

    对于posts 和comments,我倾向于验证foreign_key 而不是关联。这部分是由于更好的性能,但测试Comment 模型将独立于Post 模型。

    对于CommentPost的例子,在创建评论时,我会设置关联(即comment.post = postpost.comments.create!)而不是foreign_key(即comment.post_id = post.id),所以我知道帖子存在(这就是为什么我不验证关联的存在)。但是,在不太可能的数据损坏情况下,这不会对应用程序产生重大影响(只有一条评论不会与现有帖子相关联)。

    在其他需要绝对确定关联存在的情况下,您可以非常安全并验证关联(例如,CreditCard 属于 UserInvoice 属于Account)。

    【讨论】:

      【解决方案2】:

      博客文章 http://railsguides.net/belongs-to-and-presence-validation-rule1/ 的 cmets 部分,链接到答案 https://stackoverflow.com/a/25808182/38765 表明有些人在 post_id 上进行验证只是因为他们不知道其他方法:

      感谢您发布此信息!我总是在球场上得到验证。我没有 甚至考虑验证关联。

      太棒了,谢谢。这很微妙。

      有人说post_id可能有更好的性能:

      请记住,验证 :account 而不是 :account_id 将导致性能损失,因为必须查询数据库 检查关联是否存在。

      但出于性能原因,我倾向于谨慎行事。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-13
        • 1970-01-01
        • 1970-01-01
        • 2018-07-05
        相关资源
        最近更新 更多