has_and_belongs_to_many association in Rails 4

  has_and_belongs_to_many (HABTM) association in Rails 4


A has_and_belongs_to_many association directly creates a many-to-many connection between models. This blog will illustrate how to implement such relation in Rails3 using this example - if an application includes two models :-
1. Subject
2. Page
Here each 
Subject can have many Pages and each Page can appear in many Subjects.

Following are the required steps for implementing such relation :-


1. Generate the models using the command
rails g model 
Subject
rails g model 
Page


Note: you can add necessary attributes to the models.

2. Declare the models in this way

class 
Subject < ActiveRecord::Base
  has_and_belongs_to_many :pages 
end

class 
Page < ActiveRecord::Base
  has_and_belongs_to_many :subjects
end


3. On running rake db:migrate for these models, by default rails create a column id in its tables. So both 
Subjects and Pages table will have an id column.

4. Generate a rails migration for creating the join table SubjectsPages
                      
                        rake generate migration create_pages_subjects

Note: The join table name should have the name of the models in alphabetical order. Here pages come 1st and then subjects


5. In the migration file created : "
create_pages_subjects.rb" , write the following code
class CreatePagesSubjects < ActiveRecord::Migration
  def change
    create_table :subjects_pages do |t|
      t.integer :subject_id
      t.integer :page_id
    end
  end
end


Note: Remove the timestamps (created by default) attribute since it will throw an error on create/edit of the association from the UI.


6. Run rake db:migrate 
This will create a table in your database: subjects_pages

Fields will be : id,  subject_id, page_id


7. One has to give an option in the UI for adding multiple organizers to a particular event. So one can add the following code to create a multiple select drop-down for pages in the view.


pages/_form.html.erb 

<%= f.label :pages %>
<%= select_tag "pages_number", options_from_collection_for_select(Page.all, 'id', 'name',@subject.pages.map{ |j| j.id }), :multiple => true %>

This code will display a drop-down with the names of already added 
Pages.


8. In the subjects_controller.rb file

append these lines to the create and update methods


def create
@subject = Subject.new(params[:event])
@
pages = Page.where(:id => params[:pages_number])
@subject.
pages << @pages 
#associate the selected Pages to the Subject and create records in the join table


def update

@subject = Subject.find(params[:id])

@
pages = Page.where(:id => params[:organizing_team])

@subject.
pages.destroy_all   

@subject.pages << @pages

#associate the selected Pages to the Subject and create records in the join table

9. On creation/update of an 
Subject when multiple Pages are selected then the entries are added to the join table subjects_pages.






Comments

  1. Harrah's Philadelphia Casino & Hotel | DRMCD
    Discover and benefit from our casino 하남 출장안마 floor featuring 포천 출장샵 over 동해 출장마사지 100000 games. Our gaming floor 충주 출장마사지 features over 1,000 김포 출장샵 slot machines & 80 table games.

    ReplyDelete

Post a Comment

Popular posts from this blog

how to customize dashboard in active admin gem in rails 4

fibonacci series in Ruby

Write a program to Sum of Digits in JQuery?