Rails Join Table Ultimate Tutorial

This is a complete tutorial for creating join table in Ruby on Rails. It will show how to generate and create a join table and how to address associations between different models. It will also show you how to write a form with multiple select boxes and how to handle it in the controller.

Step 1: Creating a migration

First let's create join table in the Rails way, with city and cleaner as references.

rails g model Assignment city:references cleaner:references

This will create the following migration:

create_assignments.rb

class CreateAssignments < ActiveRecord::Migration
  def change
    create_table :assignments do |t|
      t.references :city, index: true, foreign_key: true
      t.references :cleaner, index: true, foreign_key: true

      t.timestamps null: false
    end
  end
end

Step 2: Modify the Model

In the model, we will configure a has_many :through association between cleaner, city, and assignment. The association declarations could look like this:

cleaner.rb

class Cleaner < ActiveRecord::Base
  has_many :assignments
  has_many :cities, through: :assignments
end

city.rb

class City < ActiveRecord::Base
  has_many :assignments
  has_many :cleaners, :through => :assignments
end

assignment.rb

class Assignment < ActiveRecord::Base
  belongs_to :city
  belongs_to :cleaner
end

You can read this example in the following way:
Cleaners through assignments have many cities that they are assigned to, while cities have many cleaners through assignments. Both cities and cleaners can have many assignments as well!

Assignments table connects the cleaner and city table through their id (city_id and cleaner_id).

Step 3: Modify the Controller

Here you should edit your cleaners controller to accept city_ids in the private cleaner_params definition.

cleaners_controller.rb

private

def cleaner_params
  params.require(:cleaner).permit(city_ids: [])
end

Be sure to cover everything with tests using RSpec and FactoryGirl!

Modify View layout

Once the backend is set the only thing left for you to do is to add the view.

In this example, you can add a multiple selection checkbox, where we can select multiple city names at once where the cleaner can be assigned at.

form.html.erb

<%= form_for(@cleaner) do |f| %>
  <p>
    <%= f.label :cities %><br />
    <% for city in City.all %>
      <%= check_box_tag "cleaner[city_ids][]", city.id, @cleaner.cities.include?(city) %>
      <%=h city.name %><br />
    <% end %>
  </p>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

We hope we managed to explain how you should create join table in Rails.

Stay connected with us just like these tables do, through newsletter subscription!