Ruby on rails 自动创建关系,除非它已存在

Ruby on rails 自动创建关系,除非它已存在,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,然而,这相当麻烦,并且会导致大量查询。我想做的事情是如此普遍,我想知道一些rails魔法是否能帮我解决这个问题?看起来像是查找\u或\u创建\u by答案是: cat.catbowls.create(bowl_id: bowl.id) unless Catbowl.where(cat_id: cat.id, bowl_id:bowl.id).present? 通过将选项cat\u id和bowl\u id传递给该方法,我们只检查这些列的唯一性,并忽略所有其他列(例如id)。首先删除cat和bo

然而,这相当麻烦,并且会导致大量查询。我想做的事情是如此普遍,我想知道一些rails魔法是否能帮我解决这个问题?

看起来像是
查找\u或\u创建\u by
答案是:

cat.catbowls.create(bowl_id: bowl.id) unless Catbowl.where(cat_id: cat.id, bowl_id:bowl.id).present?

通过将选项
cat\u id
bowl\u id
传递给该方法,我们只检查这些列的唯一性,并忽略所有其他列(例如
id
)。

首先删除cat和bowl do的“s” 类CatBowl 然后创建桥入口

猫碗 要简单地将碗与猫关联,请执行以下操作:

cat = Cat.create(name: 'tibbles')
bowl = Bowl.create(color: 'blue')

cat.com仅供参考:
请注意*此方法不是原子的*,它首先运行SELECT,如果没有结果,则尝试插入。如果有其他线程或进程,则两个调用之间都存在争用条件,可能最终会出现两个类似的记录。
令人惊讶的是,Rails的这个bug尚未修复。有人尝试过,在这里的评论中引用过-,但没有骰子。DB级别的联接表上的唯一索引将防止重复,但也会引发错误-但错误比DB中的垃圾要好。在修复此错误之前,我们最好避免抛出错误。
CatBowl.all #=> [#<Bowl id: 1, cat_id: 1, bowl_id: 1>]
cat.catbowls.create(bowl_id: bowl.id)
cat.catbowls #=> [#<Bowl id: 1, color: "blue", created_at: "2014-04-23 22:53:15", updated_at: "2014-04-23 22:53:15">]> 
CatBowl.all #=> [#<Bowl id: 1, cat_id: 1, bowl_id: 1>,#<Bowl id: 2, cat_id: 1, bowl_id: 1>]
cat.catbowls.create(bowl_id: bowl.id) unless Catbowl.where(cat_id: cat.id, bowl_id:bowl.id).present?
Catbowl.find_or_create_by(cat_id: cat.id, bowl_id: bowl.id )
cat = Cat.create(name: 'tibbles')
bowl = Bowl.create(color: 'blue')
cat.bowls << bowl 
cat.bowls << bowl unless cat.bowl_ids.include?(bowl.id)