目前我通过插入每次检查的新关系,如果它不存在:Ruby on Rails的ActiveRecord的“的has_many:通过”唯一性验证
unless Relationship.exists?(:entry_id => entry.id, :tag_id => tag.id)
我怎么能实现关系模型中这样的验证,所以它不允许在同一条目和标签之间有多个关系?
目前我通过插入每次检查的新关系,如果它不存在:Ruby on Rails的ActiveRecord的“的has_many:通过”唯一性验证
unless Relationship.exists?(:entry_id => entry.id, :tag_id => tag.id)
我怎么能实现关系模型中这样的验证,所以它不允许在同一条目和标签之间有多个关系?
class Relationship < ActiveRecord::Base
belongs_to :entry
belongs_to :tag
validates :tag_id, :uniqueness => { :scope => :entry_id }
end
假设你的模型看起来是这样的:
class Entry < ActiveRecord::Base
has_many :relationships
has_many :tags, :through => :relationships
end
class Tag < ActiveRecord::Base
has_many :relationships
has_many :entries, :through => :relationships
end
class Relationship < ActiveRecord::Base
belongs_to :entry
belongs_to :tag
end
你可以一个唯一的验证添加到您的Relationship
加盟模式:
validates_uniqueness_of :tag_id, :scope => :entry_id
的validates_uniqueness_of
方法将确保关系尚不存在,并且:scope
选项将把匹配范围限定到给定列。通过此验证通过轨道生成的SQL的样子:
SELECT `relationships`.id
FROM `relationships`
WHERE (`relationships`.`tag_id` = <tag id> AND `relationships`.`entry_id` = <entry id>)
LIMIT 1
(你会发现基本上是由您明确使用Relationship.exists?(:entry_id => entry.id, :tag_id => tag.id)
产生相同的SQL),如果一个记录被发现,验证将失败。
同样,如果您想验证唯一性,请确保您在relationships
表中的tag_id, entry_id
上有唯一密钥。请参阅this article以及上面链接的API页面的“并发性和完整性”以获取更多信息。
谢谢,但我如何添加唯一键,我仍然可以有相同的tag_id为其他条目和许多不同的标签为同一条目? add_index“relationships”,[“tag_id”],:unique => true - 我想会阻止我多次使用相同的tag_id。 – krn 2011-02-26 21:32:15
您必须为* both *列创建索引。在迁移中,它看起来像“add_index:relationships,[:tag_id,:entry_id],:unique => true'。然后,执行DBMS,如果两列的值与现有行匹配,则新行只有冲突。 – 2011-02-26 21:34:09
(这应该是*你的DBMS) – 2011-02-26 21:39:41