是否有一种简单或至少优雅的方式来防止多态has_many通过关联重复项?Rails预防重复多态has_many:通过关联
我有两个模型,故事和可以标记的链接。我正在有意识地决定不要在这里使用插件。我想真正理解所发生的一切,而不是依赖于别人的代码,我没有完全掌握。
看看我的问题是在得到,如果我跑在控制台下(假设的故事和标签对象已经存在于数据库中)
s = Story.find_by_id(1)
t = Tag.find_by_id(1)
s.tags << t
s.tags << t
我引用的Tagging加入将增加表中的两个条目到它,每个具有相同的确切数据(tag_id = 1,taggable_id = 1,taggable_type =“故事”)。这对我来说似乎不太合适。因此,在试图防止这种情况发生,我添加以下到我的标签模型:
before_validation :validate_uniqueness
def validate_uniqueness
taggings = Tagging.find(:all, :conditions => { :tag_id => self.tag_id, :taggable_id => self.taggable_id, :taggable_type => self.taggable_type })
if !taggings.empty?
return false
end
return true
end
和它的作品几乎是预期的,但如果我试图重复的标签添加到一个故事或链接我得到一个ActiveRecord :: RecordInvalid:验证失败的异常。看起来,当你添加一个关联到列表时,它会调用save! (而不是保存sans!)方法,如果出现问题而不是仅仅返回false,就会引发异常。这不完全是我想要发生的事情。我想我可以围绕任何试图用try/catch添加新标签的尝试,但是这与你不应该期待你的例外并且这是我期望发生的事情相反。
有没有更好的方法来做到这一点,当我想要做的只是默默无闻地将对象保存到数据库因为重复存在而不会引发异常?
这几乎就是我想要的。不过,我不确定如何去重载标签<<方法。我试着复制add_tags方法,并将其重命名为“tags <<”,但每当我尝试调用它时,它都会给我带来NoMethodError:未定义的方法'标签',用于#。我真的很喜欢<<方法被重载,因为使用它似乎更自然。 –
seaneshbaugh
2010-05-22 20:26:11
噢,我忘了,你必须定义一个标签方法,它返回一个具有'<<'方法的对象。但是,self.tags << new_tags无论如何都不起作用,因为它只会尝试在标签集合中添加一组标签作为元素。你会想为该行使用'self.tags + = new_tags'。答案已更新。 – 2010-05-23 07:10:23