class Cat < ActiveRecord::Base
has_many :catbowls
has_many :bowls, through: :catbowls
end
class CatBowl < ActiveRecord::Base
belongs_to :cats
belongs_to :bowls
end
class Bowl < ActiveRecord::Base
has_many :catbowls
has_many :cats, through: :catbowls
end
In the rails console I can give a bowl to a cat:
cat = Cat.create(name: 'tibbles')
bowl = Bowl.create(color: 'blue')
cat.catbowls #=> []
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">]
This makes sense, and the following association exists:
CatBowl.all #=> [#<Bowl id: 1, cat_id: 1, bowl_id: 1>]
However, here's my problem. If I create the association again, it doesn't actually change the result, but I do get an ineffectual identical catbowl relationship.
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">]>
This relationship is identical to the previous one and utterly useless:
CatBowl.all #=> [#<Bowl id: 1, cat_id: 1, bowl_id: 1>,#<Bowl id: 2, cat_id: 1, bowl_id: 1>]
So how can I stop an existing relationship from being created? What method chain should be used to replace cat.catbowls.create, and create a relationship unless it already exists?
I could use an unless statement to do this,
cat.catbowls.create(bowl_id: bowl.id) unless Catbowl.where(cat_id: cat.id, bowl_id:bowl.id).present?
however this is pretty cumbersome and results in a lot of queries. What I want to do is so common I'm wondering if some rails magic can help me out?