Beginners Tutorial: Routing in Rails 2.0 (with REST) – Part 4 of n

May 11, 2008

Part 5

The routes we have discussed so far are known as simple routes. I have been referring to them as custom routes, but ‘simple routes’ is the correct term. The default route we discussed in part 3 is also a simple route. The aim is to move onto RESTful routes, sometimes called resource routes. RESTful routes are built on top of named routes. Therefore we must first cover named routes, and that is what part 4 is all about.

Part 4

Introduction

Referring back to part 1, the routing system has two main functions:
Interpreting a request URL
Generating a request URL

We had a detailed look at route generation and interpretation in part 2, but let’s have another quick look at it. Let’s assume, for some insane reason, that we defined the following route in the music_store routes.rb file:

map.connect ‘apples/bananas/:id’, :controller => “albums”, :action => “show”

link_to would use this rule to generate a URL, this can be seen in the following line extracted from index.html.erb:

link_to ‘Show’, :controller => “albums”, :action => “show”, :id => album.id

This could generate a URL of: http://localhost:3000/apples/bananas/7
And when given this request, Rails would handle it correctly e.g. the show action will be called on the albums controller and the show view will be sent as the response to the browser.

Coming back to the real world, we are more likely to define the routing rule like this:
map.connect ‘albums/show/:id’, :controller => “albums”, :action => “show”

link_to (and friends) would then generate a URL like this:
http://localhost:3000/albums/show/7.

To show the index (the listing of the albums) we could define a rule like this:
map.connect ‘albums/index’, :controller => “albums”, :action => “index”

The matching link_to in edit.html.erb is:
link_to ‘Back’, :controller => “albums”, :action => “index”

Looking at the last example, there is some repetition. Both lines contain:
:controller => “albums”, :action => “index”

The link_to method needs this (controller, action) information to obtain the URL. If we had the URL stored as some global variable, or method, then we could simply pass that into link_to. link_to could use this ‘literal’ URL without needing to generate one.
This could look something like: link_to ‘Back’, albums_index_url
This is one of the main ideas behind named routes.

Read the rest of this entry »


Beginners Tutorial: Routing in Rails 2.0 (with REST) – Part 3 of n

April 27, 2008

Part 4

Part 3

At the end of part 2, routes.rb looked like this:

ActionController::Routing::Routes.draw do |map|
  map.connect 'music', :controller => "albums", :action => "index"
  map.connect '', :controller => "albums", :action => "index"
  map.connect 'music/show/:id', :controller => "albums", :action => "show"
  map.connect 'music/delete/:id', :controller => "albums", :action => "destroy"
  map.connect 'music/edit/:id', :controller => "albums", :action => "edit"
  map.connect 'music/update/:id', :controller => "albums", :action => "update"
  map.connect 'music/new', :controller => "albums", :action => "new"
  map.connect 'music/create', :controller => "albums", :action => "create"
end

To simplify things, let’s remove the routing rule for the empty URL. Remove line 3.

We can no longer browse to http://localhost:3000/, but we can still browse to http://localhost:3000/music. Besides that, the site should continue to work as before.
Looking at the routes.rb file we see 7 rules defined.

ActionController::Routing::Routes.draw do |map|
  map.connect 'music', :controller => "albums", :action => "index"
  map.connect 'music/show/:id', :controller => "albums", :action => "show"
  map.connect 'music/delete/:id', :controller => "albums", :action => "destroy"
  map.connect 'music/edit/:id', :controller => "albums", :action => "edit"
  map.connect 'music/update/:id', :controller => "albums", :action => "update"
  map.connect 'music/new', :controller => "albums", :action => "new"
  map.connect 'music/create', :controller => "albums", :action => "create"
end

We have 7 rules and only one database table. Does this mean we need to add 7 more rules for every table we add? No, there are ways to reduce the amount of explicitly defined rules.

When Rails receives a URL it tries to find a matching routing rule. It does this by comparing the URL to the pattern string in the rule.
The pattern string for map.connect ‘music/create’, :controller => “albums”, :action => “create” Is: music/create

The pattern string for map.connect ‘music/edit/:id’, :controller => “albums”, :action => “edit”
Is: music/edit/:id

The :id is a Ruby symbol and is referred to as a receptor. If you are new to Ruby you may not be too familiar with symbols. I once came across a short and sweet description of a symbol “A symbol is the name badge, not the person”. I may have read that in here.

A receptor is used as a wildcard. It matches anything that it is compared against. The wildcard receptor gets passed into the controller action within the params hash e.g.

def edit
    @album = Album.find(params[:id])
end

You can change :id to almost anything as long as you remember to change it in the controller and in the views where the URL is generated e.g. when using link_to. I recommend you use :id as that is the convention.

Read the rest of this entry »


Beginners Tutorial: Routing in Rails 2.0 (with REST) – Part 2 of n

March 25, 2008

Part 3

Thank you to all of you who took the time to give me feedback on part 1. Most of the feedback was positive. A friend of mine suggested that I drop the sound effects and stick to the subject matter, I graciously accepted his advice. Therefore this post should have a better fact to fluff ratio than the previous one. On that note, let’s begin…

Part 2

In part 1 we learnt that the routing system has two main functions:
• Interpreting a request URL
• Generating a request URL
Rails uses the same routing rule to interpret a URL and to generate a URL.
Note that routing rules are often called routes, I will use the terms interchangeably.

Now we will start fixing our music_store application from part 1.

Read the rest of this entry »


Beginners Tutorial: Routing in Rails 2.0 (with REST) – Part 1 of n

March 15, 2008

Part 2

About this series

This is a series for beginners wanting to learn about routing in Rails 2.0. This first post is aimed at exploring the behaviour of routing in Rails. It examines what happens when the routing system is given a certain URL. Future posts will examine the ‘hows’ and ‘whys’ of this behaviour. The plan is to start with the basics and move towards the advanced topics. There is only a brief mention of RESTful routing in this post. I plan to delve deeper into that topic at a later stage.

I will continue with this series only if there is a demand for further posts, and if time permits. If nobody is interested, then I will come up with a new topic and start pestering the world all over again!

Introduction

The routing subsystem is at the heart of a Rails application. By looking at the following image, we can see the role of the routing system.

RoutingInRails

The diagram is a modified version of a diagram found in Flexible Rails.

As the picture depicts, in a Rails application the process begins with a request from the browser. This request is passed into the Rails routing system. The routing system examines the request and is able to determine the following information:

  • Which controller to instantiate
  • Which action (method) to invoke on that controller
  • The parameters, if any, to pass into the action

When receiving a correctly formatted request URL the routing system will instantiate the specified controller, call the appropriate action and pass in the supplied method parameters, if required. The controller will then perform the necessary action and Rails will render the relevant view. This will result in the browser receiving a response and the round trip is complete. This is oversimplified, but it does show the importance of the routing system.

If the request is not in the correct format the routing system may not be able to infer the correct action to take. Therefore it is important that the format is correct. We are in luck as the Rails routing system also helps us to generate requests in the correct format.

In short, the routing system has two main functions:

  • Interpreting a request URL
  • Generating a request URL

The routing system performs these functions by using routing rules, defined in Ruby code as opposed to XML. The rules can be found in the config/routes.rb Ruby file. Each rule is used to both interpret and to generate a related request URL.

I could go into more theory here but, as with many things, the best way to get to grips with routing is to do it!

Read the rest of this entry »