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.
This post was originally published at Kolosek blog.
Top comments (0)