Ruby on Rails: Many-to-Many Relationship
June 17th, 2008 | by hantu |In Rails, there are two ways (that I know of) to define many-to-many relationship, one of which is by using has_and_belongs_to_many (a.k.a HABTM), and the other one is by using through association.
Differences between the two methods can be seen in this comparison. Episode 47 of Railscasts also give a good understanding of the two methods, which is how I learned about the two different methods to define many-to-many relationship.
Our examples below are based on the following scenario (a simplified version of the project I am working on):
An application can have many categories.
A category has many applications.
We need some sort of join table to define the categorisation.
I have generated two models: app and category.
script/generate model app name:string script/generate model category name:string
HABTM Method
In order to generate the join table, I did:
script/generate migration create_apps_categories
In your migration file:
def self.up create_table :apps_categories, :id => false do |t| t.references :app t.references :category t.timestamps end end
In models/app.rb:
class App < ActiveRecord::Base has_and_belongs_to_many :categories end
In models/category.rb:
class Category < ActiveRecord::Base has_and_belongs_to_many :apps end
Through Association
A different approach is used here, particularly useful when you need extra fields in your join table.
Create a model called Categorisation:
script/generate model categorisation app:references category:references
Now, in models/categorisation.rb:
class Categorisation < ActiveRecord::Base belongs_to :app belongs_to :category end
In models/app.rb:
class App < ActiveRecord::Base has_many :categorisations has_many :categories, :through => :categorisations end
Finally, in models/category.rb:
class Category < ActiveRecord::Base has_many :categorisations has_many :apps, :through => :categorisations end
All these information are based on my understanding, I don’t know if its the right way of doing it, since I am fairly new to Rails. Leave a comment if there’s a better way, or if I am doing it wrongly.
1 Trackback(s)
You must be logged in to post a comment.