Reputation: 9895
I'm having a hard time figuring out how to association one of my models with multiple of another.
As it is now, I have:
class ModelA < ActiveRecord::Base
has_many :model_b
end
class ModelB < ActiveRecord::Base
belongs_to :model_a
end
However... ModelB needs to belong to not only one instance of ModelA, but possibly three. I know there is a has_many :through, but I'm not sure how it would work in this case. EVERY instance of ModelA will always have exactly three instances of ModelB. But as said before, ModelB can belong to more than just one instance of ModelA.
Upvotes: 30
Views: 35906
Reputation: 23307
Many-to-many relationships in rails don't use belongs_to
. Instead, you want to use one of a couple options. The first is has_and_belongs_to_many
:
# app/models/category.rb
class Category < ActiveRecord::Base
has_and_belongs_to_many :items
end
# app/models/item.rb
class Item < ActiveRecord::Base
has_and_belongs_to_many :categories
end
And you'll need to add an extra join table in your database, with a migration like this:
class AddCategoriesItems < ActiveRecord::Migration
def self.up
create_table :categories_items, :id => false do |t|
t.integer :category_id
t.integer :item_id
end
end
def self.down
drop_table :categories_items
end
end
You can see that the join table's name is the combination of the two other tables' names. The tables must be mentioned in alphabetical order as above, and the :id => false
needs to be there, since we don't want a primary key on this table. It will break the rails association.
There's also another, more complex method known as has_many :through
if you need to store info about the relationship itself. I've written a whole article detailing how to do both methods, and when to use each:
Basic many-to-many Associations in Rails
I hope this helps, and contact me if you have any other questions!
Upvotes: 54
Reputation: 5721
This is what @Jaime Bellmyer used
# app/models/category.rb
class Category < ActiveRecord::Base
has_and_belongs_to_many :items
end
# app/models/item.rb
class Item < ActiveRecord::Base
has_and_belongs_to_many :categories
end
I would recommend using this
# app/models/category.rb
class Category < ActiveRecord::Base
has_many :category_items
has_many :items, :through => :category_items
end
# app/models/item.rb
class Item < ActiveRecord::Base
has_many :category_items
has_many :categories, :through => :category_items
end
# app/models/category_items.rb
class CategoryItems < ActiveRecord::Base
belongs_to :category
belongs_to :items
end
If you use this you will have a join model which will give you more control over handling Category and Item. But using what @Jaime suggested you will have only a join table and not a model, which will not be under control.
Upvotes: 35