哪种方法可用于验证belongs_to关联的存在?

时间:2015-10-28 02:14:28

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

鉴于

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?是无关的 - 它正在讨论验证帖子至少有一条评论,这与我提出的要求不同。

2 个答案:

答案 0 :(得分:1)

我不认为单个案例适合所有情况。

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

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

在其他情况下,您需要绝对确定关联存在,您可以非常安全并验证关联(例如comment.post_id = post.id属于CreditCard或{{ 1}}属于User)。

答案 1 :(得分:0)

帖子http://railsguides.net/belongs-to-and-presence-validation-rule1/的评论部分与答案https://stackoverflow.com/a/25808182/38765相关联,表明有些人只是因为他们不了解其他方法而对post_id进行验证它:

  

感谢您发布此内容!我一直在现场验证。我没有   甚至考虑验证协会。

  

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

有人说post_id可能有更好的表现:

  

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

但出于性能原因,我倾向于担心做事。