Ruby on Rails one to many database relationships

Using : Ruby 1.9.2, Rails 3.1.3

Please note : I’m new to all this Ruby on Rails stuff, I’m posting these articles so if I make mistakes hopefully people will point them out.

As a developer on top of the Microsoft ASP.NET and SQL Server stack you have a lot of good tools at your disposal, but a lot of these tools abstract developers away from what is really happening under the covers. Whether that is a good or bad thing I’ll leave for another post.

Creating a one to many relationship in a .NET application is as simple as:
1, Creating the database tables including necessary foreign keys
2, Add the tables and map the relationship using Linq 2 SQL or Entity Framework

…and away you go.

Ruby on Rails is quite a bit different as their is no visual designer for modeling the relationships. It is done through adding attributes to model classes. Here’s a simple walk through on how to create a simple one to many relationship where a Category can have many Products belonging to it.

First lets create a new rails app called store, in a terminal window type:

rails new store

Change into the store directory, and lets use scaffold to create our category and product application components:

rails g scaffold category name:string
rails g scaffold product name:string description:text category_id:integer

Notice that we add the foreign key field of category_id to this command.
Open up the directory in textmate and edit the model files for category and product. In category.rb add:

has_many:products

and in product.rb add

belongs_to:category

Now back in your terminal window run rake db:migrate to create your product and category tables, and run rails s to start the application.

Open a browser and navigate to http://localhost:3000/categories and add a couple of categories such as cars and books.
Now if you navigate to http://localhost:3000/products you will notice that if you try to create a new product you will have to know the exact category_id the product should belong to. What would work better is if you had a nice drop down menu to select the category. Lets do this!

Open up the products_controller.rb and find the new method below the @product = Product.new add the following line:

@categories = Category.all

Also find the edit method in the products_controller, and add the same line.

This will give us the category data to populate our drop down selection list. We now need to change the form for creating a new product. In Views/Products open the file _form.html.erb and change the line:

<%= f.text_field :category_id %>

to

<%= collection_select(:product, :category_id, @categories, :id, :name, {:prompt => false })  %>

:product – the name of the object you are setting the value for, eg in our form the object is @product set in the form helper
:category_id – the name of the property to be set by the selection
@categories – the collection of objects to display in the drop down
:id – the value property for each object displayed
:name – the display property for each object displayed
{:prompt => false} – this is optional, and is set so no prompt (such as ‘Please select an item’) is displayed.

If you save all the files now and go to create a new product you’ll notice that you get a nice drop down list of categories to chose from. Hurrah!

The final thing you may want to improve is the index.html.erb and show.html.erb views within the Views/Products folder. At the moment these two views will display the category_id number rather than the actual name of the category. If you want to fix this simply change:

<%= product.category_id %>

to

<%= product.category.name %>

in the index.html.erb and show.html.erb files.

This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *