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.