← back to home

How I model Many to many associations with checkbox collection in Rails

By Ole Ingemann Kjørmo, Nov 21, 2017

First of all, why do we need Active Record Relations and associations? Because associations make common operations simpler, faster and will save you a lot of time. It will also lead to better results for the end user. Associations extend your Rails-objects with methods that can be accessed anywhere to list, select or filter related objects with less code. Your code will also be dryer and easier to read.

Once you’ve seen the benefits, you’ll be glad you spent the time learning it. And once you’ve nailed it for one project, the next time will be easy as brewing your morning coffee. Features like these are the main advantages of Rails in the first place, so make sure you don’t miss it.

In this example I will be using a Band-model and a Tag-model. A Band has zero, one or many tags, and the same with tags and related bands. As for the final result, we will be able to display a list bands with all it’s corresponding tags, and list all bands that’s tagged with respect to a certain tag.

To complete the use case, I will make a simple user interface with checkboxes (Checkbox collection-helper) to do our band-tagging.

I assume you’ve already got the following up and running:

•The band model

•The tag model

Appropriate controllers and views for the two

The key here is to create a third model, that will serve as a bridge between the two main models. It will function as storage for what’s called a JOIN clause between the band and tag model. A JOIN clause is used to combine rows from two or more tables, based on a related column between them. It’s a classic in SQL terms. You can name this bridging model whatever, but I prefer to use the names of the two models that it will serve.

Lets start by creating the BandTag model

rails generate model BandTag

This will generate som stuff including a file called something like

db/migrate/20171121194425_create_band_tags.rb

To create the appropriate new column for our model from this file, simply run

bundle exec rake db:migrate

Now I need to create a migration for the two rows that will link the actual band to tag. Depending on the Rails version there are shortcuts for this operation, but I like to write it manually as a seperate migration:

rails generate migration AddReferencesToBandTags

This will create a new migration file in the db/migrations folder that we will change to

class AddReferencesToBandTags < ActiveRecord::Migration
  def change 
    add_reference :band_tags, :band, index: true, foreign_key: true 
    add_reference :band_tags, :tag, index: true, foreign_key: true 
  end 
end

Then I’ll add the relation connection in my two initial models, starting with band.rb:

class Band < ActiveRecord::Base 
  has_many :band_tags 
  has_many :tags, :through => :band_tags
end

…and also to the Tag model, file tab.rb:

class Tag < ActiveRecord::Base
  has_many :band_tags
  has_many :bands, :through => :band_tags
end

Finally, we add the belongs_to attribute to the bridging model, band_tag.rb:

  class BandTag < ActiveRecord::Base
    belongs_to :tag
    belongs_to :band
  end


hello
hello
hello

Let’s continue later with the views and checkboxes… Stay tuned!

Test to see if incremental builds are working now.

← back to oleingemann.com

This is where a douchier person would write copyright. Don't copy directly, or I will have to crush you.