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. 1 Trackback(s)

  2. Jul 25, 2008: 4 Essential & 7 Optional Ruby on Rails Tutorials « BendTheBlock

You must be logged in to post a comment.