Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Open Source

Rails Routing


Bound Parameters

Recognition. The bound parameters -- key/value pairs in the hash of options at the end of the route's argument list -- determine what's going to happen if and when this route matches an incoming URL. Let's say someone connects to:


http://localhost:3000/recipes_for/apples

This URL will match the ingredient route. The result will be that the show action of the recipes controller will be executed (and the string "apples" will be made available too, as you'll see later).

To see why, look at the route again:


map.connect 'recipes_for/:ingredient',
  :controller => "recipes",
  :action => "show"

The :controller and :action keys are "magic": This route, when matched by a URL, will always take the visitor to exactly that controller and that action. You'll see techniques for matching controller and action based on "wildcard" matching shortly. In this example, though, there's no wildcard involved. The controller and action are hard-coded.

Generation. To generate a URL for use in your code, you provide values for all the necessary bound parameters. That way, the routing system can do enough match-ups to find the route you want. The parameters are usually bundled in a hash. For example, to generate a URL from the ingredient route, you'd do something like this:


<%= link_to "Recipe for apples",
   :controller => "recipes",
   :action => "show",
   :ingredient => "apples" %>

The values "recipes" and "show" for :controller and :action will match the ingredient route, which contains the same values for the same parameters. That means the pattern string in that route will serve as the template -- the blueprint -- for the generated URL. (The use of a hash to specify URL components is common to all the methods that produce URLs (link_to, redirect_to, form_for, etc.). Underneath, these methods are making their own calls to url_for, a lower-level URL generation method that we'll talk about more a little further on.)

We've left :ingredient hanging. It's a wildcard component of the pattern string.

Wildcard Components ("Receptors")

Recognition. The symbol :ingredient inside the quoted pattern in the route is a wildcard or variable. You can think of it as a receptor: Its job is to be latched on to by a value. Which value latches on to which wildcard is determined positionally, lining the URL up with the pattern string:


http://localhost:3000/recipes_for/apples <i>Someone connects to this URL...</i><br>
   'recipes_for/:ingredient' <i>and it matches this pattern string</i>.

The :ingredient receptor, in this example, receives the value "apples" from the URL. For you, this means that the value params[:ingredient] will be set to the string "apples". You can access that value inside your recipes/show action.

Generation. When you generate a URL, you have to supply values that will attach to the receptors -- the wildcard symbols inside the pattern string. You do this using key => value syntax. That's the meaning of the last line in the previous example:


<%= link_to "Recipe for apples",
   :controller => "recipes",
   :action => "show",
   :ingredient => "apples" %>

In this call to link_to, we've provided values for three parameters. Two of them are going to match hard-coded, bound parameters in the route; the third, :ingredient, will be assigned to the slot in the URL corresponding to the :ingredient slot in the pattern string. But they're all just hash key/value pairs. The call to link_to doesn't "know" whether it's supplying hard-coded or wildcard values. It just knows (or hopes!) that these three values, tied to these three keys, will suffice to pinpoint a route -- and therefore, a pattern string, and therefore, a blueprint for a URL.

Static Strings

Recognition. Our sample route contains a static string inside the pattern string: recipes_for. This string anchors the recognition process. When the routing system sees a URL that starts with /recipes_for, it will match that to the static string in the ingredient route. Any URL that does not contain the static string recipes_for in the leftmost slot will not match this route.

Generation. Static strings in the route simply get placed, positionally, in the URL that the routing system generates. Thus, the earlier link_to example will generate:

<a href="http://localhost:3000/recipes_for/apples">Recipes for apples</a>

The string recipes_for did not appear in the link_to call. The parameters of the link_to call triggered a match to the ingredient route. The URL generator then used that route's pattern string as the blueprint for the URL it generated. The pattern string stipulates the substring recipes_for. URL recognition and URL generation, then, are the two jobs of the routing system. It's a bit like the address book stored in a cell phone. When you select "Gavin" from your contact list, the phone figures out the phone number. And when Gavin calls you, the phone figures out from the phone number that the caller is Gavin; that is, it recognizes the number and maps it to the value "Gavin," which is displayed on the phone's screen.

Rails routing is a bit more complex than cell phone routing because variables are involved. It's not just a one-to-one mapping. But the basic idea is the same: Recognize what comes in, and generate what goes into the code.

We're going to turn next to the routing rules themselves. As we go, you should keep the recognition/generation dual purpose in mind. Two principles are particularly useful to remember:

  • The same rule governs both recognition and generation. The whole system is set up so that you don't have to write rules twice. You write each rule once, and the logic flows through it in both directions.
  • The URLs that are generated by the routing system (via link_to and friends) make sense only to the routing system. The path recipes_for/apples, which the system generates, contains not a shred of a clue as to what's supposed to happen -- except insofar as it maps to a routing rule.

The routing rule then provides the necessary information to trigger a controller action. Someone looking at the URL without knowing the rules won't know what the URL means. You'll see how these play out in detail as we proceed.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.