Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Model, belongs to many

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.

like image 352
ardavis Avatar asked Dec 09 '10 04:12

ardavis


People also ask

Can a model belong to multiple models?

Yes a model can belong to more than one model.

What has and belongs to many or has many through?

Stories can belong to many categories. Categories can have many stories. has_many :through gives you a third model which can be used to store various other pieces of information which don't belong to either of the original models. Person can subscribe to many magazines.

Does Rails have one relationship?

Ruby on Rails ActiveRecord Associations has_oneA has_one association sets up a one-to-one connection with another model, but with different semantics. This association indicates that each instance of a model contains or possesses one instance of another model.


1 Answers

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!

like image 97
Jaime Bellmyer Avatar answered Oct 05 '22 19:10

Jaime Bellmyer