2012-11-15 34 views
3

考虑下面的简化模型我应该验证连接表中的外键吗?

class Article < ActiveRecord::Base 
    has_many :taggings 
    has_many :tags, through: :taggings 
end 

class Tag < ActiveRecord::Base 
    has_many :taggings 
    has_many :articles, through: :taggings 
end 

class Tagging < ActiveRecord::Base 
    belongs_to :tag 
    belongs_to :article 
    validates :tag_id, :article_id, presence: true 
end 

我几乎跟着tagging railscast除了我试图写的测试它。

标签模型中的验证不在railscast中使用,但是我自己添加了这个验证,这让我很头疼。

如果我创建一个新的文章中,我可以通过标签列表:

a = Article.new(title: "title", tag_list: "tag 1, tag 2") 
a.valid? 
#=> false 
a.errors 
# => 
    @base=#<Article id: nil, title: "title">, 
    @messages={:taggings=>["is invalid", "is invalid"]}> 

因此,它看起来像我的标签类的验证是造成第二十创建失败,因为article_id是尚未公布。

人们通常在这里做什么?习惯上添加这样的验证来连接表还是可以跳过?

+0

您打算如何验证这些限制?你在哪种情况下期望失败?请花点时间思考并尝试自己回答;-) 提示:如果发生以下情况,会发生什么情况:tag_id或:article_id不在那里? – awenkhh

+1

那么,如果他们不在那里,标签就不会出现在屏幕上,真的没什么大不了的。我想应该没问题了。 – stephenmurdoch

+1

所以你去;-)。我会建议删除它们,因为它们不会给你的应用程序带来任何稳定性;-) – awenkhh

回答

1

我会建议Tagging验证存在:tag:article,而不是ID。这有两个好处:

  1. 如果文章是新记录,Tagging仍然有效。

  2. 如果article_id无效(例如-1),则Tagging将无效。

我不同意以前的评论者的建议,完全删除验证,验证有助于避免创建不良记录。例如,带有文章但不是标签的Tagging

+0

啊,谢谢你的回复,明天我会试一试,看起来这是最好的方法做到这一点,聪明的想法:) – stephenmurdoch

相关问题