SlideShare a Scribd company logo
A Many-to-Many tutorial for Rails
                                                 th
                                      September 4 , 2005

                         Creative Commons: Attribution-ShareAlike 2.5
                         Originally by Jeffrey Hicks @ http://jrhicks.net



Introduction
This brief tutorial is a start-to-finish example of the Model, View, and Controller required
for a many-to-many relationship.

This is a follow-along tutorial for a finance application so go ahead and create your rails
app, configure your database.yml, and start your server.
I. Model
Our example application will model financial expenses and tags. To work with rail’s
default expectations we follow a strict naming convention for the database table names
and fields.




Notice the required naming conventions.

   •   expenses is the plural form of expense
   •   tags is the plural form of tag
   •   both primary fields use the lowercase id
   •   the relating table is in alphabetical order expenses_tags
   •   the field relating to a tag’s id is tag_id
   •   the field relating to an expense’s id is expense_id

Create your database using the following schema.


       CREATE TABLE `expenses` (
         `id` int(11) NOT NULL auto_increment,
         `amount` float NOT NULL default '0',
         PRIMARY KEY (`id`)
       ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

       CREATE TABLE `tags` (
         `id` int(11) NOT NULL auto_increment,
         `name` varchar(100) NOT NULL default '',
         PRIMARY KEY (`id`)
       ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

       CREATE TABLE `expenses_tags` (
         `expense_id` int(11) NOT NULL default '0',
         `tag_id` int(11) NOT NULL default '0'
       ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Generate your Scaffold for the expense and tag models.




Edit expense.rb to tell your expense model that it has_and_belongs_to_many
:tags
2. View
To allow our web visitors to relate an expense with many tags, we are going to
use multiple checkboxes. This is how it will look.




Our form will generate dynamically from the tags in the database. Execute the
following SQL to populate our example database.


      Insert into tags(name) values ('food');
      Insert into tags(name) values ('restaurant');
      Insert into tags(name) values ('lodging');
Our view should depend on the expenses_controller to load the tags. Add the
@tags=Tag.find_all line to both the new and edit methods as depicted in line 17
& 32 below.
Now we will actually customize our edit and new views. We can do this in one
location; edit your expenses_form.rhtml to include lines 7 through 13.
The tags of existing expenses should be checked when we edit. To enable this
we add the following if statement to line 12.

      <%if @expense.tags.include? tag%>checked="checked"<%end%>
We will also edit the list view, so that we will be able to view our tags. Add the
code on lines 8 and 17-19 to your list.rhtml
3. Controller
The expense_controller’s update and create method receive the requests from the edit
and new view. To store the relationship we need to convert the tag_ids to actual Tag
objects with Tag.find(@params[:tag_ids]) if @params[:tag_ids].

The if @params[:tag_ids] prevents a nil object error when the user doesn’t select
any tag.

Add the lines 22 & 38 to expenses_controller.rb
Optionally
If you intention was to force the user to select a tag, I’ve been told to add this to
the expense model. (expense_controller.rb)

def validate
       if tags.blank?
               errors.add_to_base("You must specify a tag")
       end
end
Conclusion
Add an expense with multiple tags.




View the stored tags after you hit the Create button.
Edit the new expense to see stored tags as checked.




Check out the database entries in the expenses_tags table.
Thanks
August 9, 2005 - Sheldon Hearn noticed a transactional condition with the database.
Where @expense.tags.clear and @expense.tags<<Tag.find(params[:tag_ids]) should
be replaced with a single @expense.tags=Tag.find(params[:tag_ids])

August 9, 2005 – Ecow pointed out multiple documentation errors where I failed to
provide the tags table schema, missing code for assigning attributes on expense
creation, and multiple incorrect references to view and controller methods.

August 11, 2005 – Spiralis pointed out that when editing existing tags … the existing
tags should be checked.

August 17, 2005 – Brian NG suggested a fix for allowing existing tags to be checked.

August 25 – Brandt proposed a solution to the nil object error received when the user
doesn’t select a tag.

More Related Content

PDF
Has Many And Belongs To Many
guest80d303
 
DOCX
Android list view tutorial by Javatechig
Javatechig Resources for Developers
 
PPTX
Vlookup In Excel
dinesh takyar
 
PPT
Entity Attribute Value (Eav)
Tâm
 
PPTX
View Inheritance in Odoo 15
Celine George
 
PPTX
Practice create procedure
cit gubbi
 
PPT
Symfony Admin Generator - generator.yml
Ravi Mone
 
PDF
USING VLOOKUP FUNCTION
Ruffson Panganiban
 
Has Many And Belongs To Many
guest80d303
 
Android list view tutorial by Javatechig
Javatechig Resources for Developers
 
Vlookup In Excel
dinesh takyar
 
Entity Attribute Value (Eav)
Tâm
 
View Inheritance in Odoo 15
Celine George
 
Practice create procedure
cit gubbi
 
Symfony Admin Generator - generator.yml
Ravi Mone
 
USING VLOOKUP FUNCTION
Ruffson Panganiban
 

What's hot (10)

DOCX
Android practice of layout in application-chapter6
Dr. Ramkumar Lakshminarayanan
 
PDF
Introduction to oracle functions
Nitesh Singh
 
PPT
Les06
Sudharsan S
 
PPTX
Lab4 join - all types listed
Balqees Al.Mubarak
 
PPT
Devry bis-155-i lab-6
shyaminfo104
 
PDF
70 562
Pragya Rastogi
 
PPT
Les17
Vijay Kumar
 
PPT
Excel 2007 Unit K
Raja Waseem Akhtar
 
PPT
Les18
Vijay Kumar
 
DOC
Sql task
Nawaz Sk
 
Android practice of layout in application-chapter6
Dr. Ramkumar Lakshminarayanan
 
Introduction to oracle functions
Nitesh Singh
 
Lab4 join - all types listed
Balqees Al.Mubarak
 
Devry bis-155-i lab-6
shyaminfo104
 
Excel 2007 Unit K
Raja Waseem Akhtar
 
Sql task
Nawaz Sk
 
Ad

Viewers also liked (7)

PDF
Devoxx%202008%20Tutorial
tutorialsruby
 
PDF
ruby-efl-tutorial-hsyl20
tutorialsruby
 
PDF
wtst3_pettichord3
tutorialsruby
 
PDF
rails.html
tutorialsruby
 
PDF
lab56_db
tutorialsruby
 
PDF
Accessing_MySQL_from_Ruby
tutorialsruby
 
PDF
rubyonrails
tutorialsruby
 
Devoxx%202008%20Tutorial
tutorialsruby
 
ruby-efl-tutorial-hsyl20
tutorialsruby
 
wtst3_pettichord3
tutorialsruby
 
rails.html
tutorialsruby
 
lab56_db
tutorialsruby
 
Accessing_MySQL_from_Ruby
tutorialsruby
 
rubyonrails
tutorialsruby
 
Ad

Similar to has_many_and_belongs_to_many (20)

PDF
Cache Money Talk: Practical Application
Wolfram Arnold
 
PDF
I Phone On Rails
John Wilker
 
PPTX
Active record(1)
Ananta Lamichhane
 
PDF
td_mxc_rubyrails_shin
tutorialsruby
 
PDF
td_mxc_rubyrails_shin
tutorialsruby
 
ODP
Ruby on rails
Mohit Jain
 
PDF
Web Development with Ruby on Rails, MyGOSSCON 2007
kamal.fariz
 
PPT
Introduction To Ruby On Rails
Steve Keener
 
PDF
RubyOnRails-Cheatsheet-BlaineKendall
tutorialsruby
 
PDF
RubyOnRails-Cheatsheet-BlaineKendall
tutorialsruby
 
PDF
Using Database Constraints Wisely
barunio
 
PDF
Rails antipattern-public
Chul Ju Hong
 
PDF
Rails antipatterns
Chul Ju Hong
 
KEY
A-Z Intro To Rails
Robert Dempsey
 
PDF
A Z Introduction To Ruby On Rails
railsconf
 
PDF
Ruby on Rails - Introduction
Vagmi Mudumbai
 
KEY
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
ODP
Ruby on Rails
Aizat Faiz
 
PDF
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Yasuko Ohba
 
PPT
Intro to Rails ActiveRecord
Mark Menard
 
Cache Money Talk: Practical Application
Wolfram Arnold
 
I Phone On Rails
John Wilker
 
Active record(1)
Ananta Lamichhane
 
td_mxc_rubyrails_shin
tutorialsruby
 
td_mxc_rubyrails_shin
tutorialsruby
 
Ruby on rails
Mohit Jain
 
Web Development with Ruby on Rails, MyGOSSCON 2007
kamal.fariz
 
Introduction To Ruby On Rails
Steve Keener
 
RubyOnRails-Cheatsheet-BlaineKendall
tutorialsruby
 
RubyOnRails-Cheatsheet-BlaineKendall
tutorialsruby
 
Using Database Constraints Wisely
barunio
 
Rails antipattern-public
Chul Ju Hong
 
Rails antipatterns
Chul Ju Hong
 
A-Z Intro To Rails
Robert Dempsey
 
A Z Introduction To Ruby On Rails
railsconf
 
Ruby on Rails - Introduction
Vagmi Mudumbai
 
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
Ruby on Rails
Aizat Faiz
 
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Yasuko Ohba
 
Intro to Rails ActiveRecord
Mark Menard
 

More from tutorialsruby (20)

PDF
&lt;img src="../i/r_14.png" />
tutorialsruby
 
PDF
TopStyle Help &amp; &lt;b>Tutorial&lt;/b>
tutorialsruby
 
PDF
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>
tutorialsruby
 
PDF
&lt;img src="../i/r_14.png" />
tutorialsruby
 
PDF
&lt;img src="../i/r_14.png" />
tutorialsruby
 
PDF
Standardization and Knowledge Transfer – INS0
tutorialsruby
 
PDF
xhtml_basics
tutorialsruby
 
PDF
xhtml_basics
tutorialsruby
 
PDF
xhtml-documentation
tutorialsruby
 
PDF
xhtml-documentation
tutorialsruby
 
PDF
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
tutorialsruby
 
PDF
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
tutorialsruby
 
PDF
HowTo_CSS
tutorialsruby
 
PDF
HowTo_CSS
tutorialsruby
 
PDF
BloggingWithStyle_2008
tutorialsruby
 
PDF
BloggingWithStyle_2008
tutorialsruby
 
PDF
cascadingstylesheets
tutorialsruby
 
PDF
cascadingstylesheets
tutorialsruby
 
&lt;img src="../i/r_14.png" />
tutorialsruby
 
TopStyle Help &amp; &lt;b>Tutorial&lt;/b>
tutorialsruby
 
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>
tutorialsruby
 
&lt;img src="../i/r_14.png" />
tutorialsruby
 
&lt;img src="../i/r_14.png" />
tutorialsruby
 
Standardization and Knowledge Transfer – INS0
tutorialsruby
 
xhtml_basics
tutorialsruby
 
xhtml_basics
tutorialsruby
 
xhtml-documentation
tutorialsruby
 
xhtml-documentation
tutorialsruby
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
tutorialsruby
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
tutorialsruby
 
HowTo_CSS
tutorialsruby
 
HowTo_CSS
tutorialsruby
 
BloggingWithStyle_2008
tutorialsruby
 
BloggingWithStyle_2008
tutorialsruby
 
cascadingstylesheets
tutorialsruby
 
cascadingstylesheets
tutorialsruby
 

Recently uploaded (20)

PDF
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
PDF
Doc9.....................................
SofiaCollazos
 
PDF
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
PDF
CIFDAQ's Market Wrap : Bears Back in Control?
CIFDAQ
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PDF
Brief History of Internet - Early Days of Internet
sutharharshit158
 
PDF
Get More from Fiori Automation - What’s New, What Works, and What’s Next.pdf
Precisely
 
PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PDF
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
PDF
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
PDF
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
PDF
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
PDF
Trying to figure out MCP by actually building an app from scratch with open s...
Julien SIMON
 
PDF
Responsible AI and AI Ethics - By Sylvester Ebhonu
Sylvester Ebhonu
 
PDF
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
PDF
Economic Impact of Data Centres to the Malaysian Economy
flintglobalapac
 
PPTX
Dev Dives: Automate, test, and deploy in one place—with Unified Developer Exp...
AndreeaTom
 
PDF
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
PDF
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
Doc9.....................................
SofiaCollazos
 
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
CIFDAQ's Market Wrap : Bears Back in Control?
CIFDAQ
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
Brief History of Internet - Early Days of Internet
sutharharshit158
 
Get More from Fiori Automation - What’s New, What Works, and What’s Next.pdf
Precisely
 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
Trying to figure out MCP by actually building an app from scratch with open s...
Julien SIMON
 
Responsible AI and AI Ethics - By Sylvester Ebhonu
Sylvester Ebhonu
 
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
Economic Impact of Data Centres to the Malaysian Economy
flintglobalapac
 
Dev Dives: Automate, test, and deploy in one place—with Unified Developer Exp...
AndreeaTom
 
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
Presentation about Hardware and Software in Computer
snehamodhawadiya
 

has_many_and_belongs_to_many

  • 1. A Many-to-Many tutorial for Rails th September 4 , 2005 Creative Commons: Attribution-ShareAlike 2.5 Originally by Jeffrey Hicks @ http://jrhicks.net Introduction This brief tutorial is a start-to-finish example of the Model, View, and Controller required for a many-to-many relationship. This is a follow-along tutorial for a finance application so go ahead and create your rails app, configure your database.yml, and start your server.
  • 2. I. Model Our example application will model financial expenses and tags. To work with rail’s default expectations we follow a strict naming convention for the database table names and fields. Notice the required naming conventions. • expenses is the plural form of expense • tags is the plural form of tag • both primary fields use the lowercase id • the relating table is in alphabetical order expenses_tags • the field relating to a tag’s id is tag_id • the field relating to an expense’s id is expense_id Create your database using the following schema. CREATE TABLE `expenses` ( `id` int(11) NOT NULL auto_increment, `amount` float NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `tags` ( `id` int(11) NOT NULL auto_increment, `name` varchar(100) NOT NULL default '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `expenses_tags` ( `expense_id` int(11) NOT NULL default '0', `tag_id` int(11) NOT NULL default '0' ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 3. Generate your Scaffold for the expense and tag models. Edit expense.rb to tell your expense model that it has_and_belongs_to_many :tags
  • 4. 2. View To allow our web visitors to relate an expense with many tags, we are going to use multiple checkboxes. This is how it will look. Our form will generate dynamically from the tags in the database. Execute the following SQL to populate our example database. Insert into tags(name) values ('food'); Insert into tags(name) values ('restaurant'); Insert into tags(name) values ('lodging');
  • 5. Our view should depend on the expenses_controller to load the tags. Add the @tags=Tag.find_all line to both the new and edit methods as depicted in line 17 & 32 below.
  • 6. Now we will actually customize our edit and new views. We can do this in one location; edit your expenses_form.rhtml to include lines 7 through 13.
  • 7. The tags of existing expenses should be checked when we edit. To enable this we add the following if statement to line 12. <%if @expense.tags.include? tag%>checked="checked"<%end%>
  • 8. We will also edit the list view, so that we will be able to view our tags. Add the code on lines 8 and 17-19 to your list.rhtml
  • 9. 3. Controller The expense_controller’s update and create method receive the requests from the edit and new view. To store the relationship we need to convert the tag_ids to actual Tag objects with Tag.find(@params[:tag_ids]) if @params[:tag_ids]. The if @params[:tag_ids] prevents a nil object error when the user doesn’t select any tag. Add the lines 22 & 38 to expenses_controller.rb
  • 10. Optionally If you intention was to force the user to select a tag, I’ve been told to add this to the expense model. (expense_controller.rb) def validate if tags.blank? errors.add_to_base("You must specify a tag") end end
  • 11. Conclusion Add an expense with multiple tags. View the stored tags after you hit the Create button.
  • 12. Edit the new expense to see stored tags as checked. Check out the database entries in the expenses_tags table.
  • 13. Thanks August 9, 2005 - Sheldon Hearn noticed a transactional condition with the database. Where @expense.tags.clear and @expense.tags<<Tag.find(params[:tag_ids]) should be replaced with a single @expense.tags=Tag.find(params[:tag_ids]) August 9, 2005 – Ecow pointed out multiple documentation errors where I failed to provide the tags table schema, missing code for assigning attributes on expense creation, and multiple incorrect references to view and controller methods. August 11, 2005 – Spiralis pointed out that when editing existing tags … the existing tags should be checked. August 17, 2005 – Brian NG suggested a fix for allowing existing tags to be checked. August 25 – Brandt proposed a solution to the nil object error received when the user doesn’t select a tag.