鉴于有许多蔬菜模型的晚餐模型,我更喜欢
dinner.vegetables << carrot
如果
,请不要添加胡萝卜dinner.vegetables.exists? carrot
然而确实如此。它每次都会添加重复记录&lt;&lt;被称为。
你可以在关联上设置一个:uniq选项,但如果有多个,它只能获取并返回一个结果,它不会ENFORCE唯一值。
我可以检查存在吗?每次我将一个obj添加到一个集合中,但这很乏味且容易出错。
我如何使用&lt;&lt;自由而不用担心错误而不是每次检查已经存在的收集成员?
答案 0 :(得分:2)
最好的方法是使用Set而不是Array:
set = Set.new
set << "a"
set << "a"
set.count -> returns 1
答案 1 :(得分:1)
如果您有一个表示晚餐和蔬菜之间多对多关系的连接模型,则可以添加ActiveRecord唯一约束。这是我使用联接模型和has_many :through
而不是has_and_belongs_to_many
的一个原因。如果可能,在数据库级别添加唯一性约束非常重要。
更新:
要使用连接模型来强制执行约束,您需要在数据库中添加一个附加表。
class Dinner
has_many :dinner_vegetables
has_many :vegetables, :through => :dinner_vegetables
end
class Vegetable
has_many :dinner_vegetables
has_many :dinners, :through => :dinner_vegetables
end
class DinnerVegetable
belongs_to :dinner
belongs_to :vegetable
validates :dinner_id, :uniqueness => {:scope => :vegetable_id} # You should also set up a matching DB constraint
end
答案 2 :(得分:0)
其他海报的想法很好,但作为另一种选择,您也可以使用例如海报在数据库级别强制执行此操作。 UNIQUE
constraint in MySQL。
答案 3 :(得分:0)
经过大量的挖掘,我发现了一些很酷的东西:before_add,这是一个关联回调,我从来都不知道甚至存在。所以我可以这样做:
has_many :vegetables, :before_add => :enforce_unique
def enforce_unique(assoc)
if exists? assoc
...
end
如果你真的需要这个是独特的,那么在数据库级别这样做是个好主意,但如果它不是关键任务,那么上面的解决方案对我来说已经足够了。
这主要是为了避免在数据库中有额外记录的icky感觉......