- The Two Purposes of Routing
- Bound Parameters
- Wildcard Components ("Receptors")
- Static Strings
- The routes.rb File
- The Ante-Default Route and respond_to
- The Empty Route
- Writing Custom Routes
- Using Static Strings
- Using Your Own "Receptors"
- A Note on Route Order
- Using Regular Expressions in Routes
- Default Parameters and the url_for Method
- Using Literal URLs
- Route Globbing
- Globbing Key-Value Pairs
- Named Routes
- What to Name Your Routes
- The Special Scope Method with_options
- Conclusion
The Ante-Default Route and respond_to
The route just before the default route (thus the "ante-default" route) looks like this:
map.connect ':controller/:action/:id.:format'
The .:format at the end matches a literal dot and a wildcard "format" value after the id field. That means it will match, for example, a URL like this:
http://localhost:3000/recipe/show/3.xml
Here, params[:format] will be set to xml. The :format field is special; it has an effect inside the controller action. That effect is related to a method called respond_to.
The respond_to method allows you to write your action so that it will return different results, depending on the requested format. Here's a show action for the items controller that offers either HTML or XML:
def show @item = Item.find(params[:id]) respond_to do |format| format.html format.xml { render :xml => @item.to_xml } end end
The respond_to block in this example has two clauses. The HTML clause just consists of format.html. A request for HTML will be handled by the usual rendering of the RHTML view template. The XML clause includes a code block; if XML is requested, the block will be executed and the result of its execution will be returned to the client.
Here's a command-line illustration, using wget (slightly edited to reduce line noise):
$ wget http://localhost:3000/items/show/3.xml -O - Resolving localhost... 127.0.0.1, ::1 Connecting to localhost|127.0.0.1|:3000... connected. HTTP request sent, awaiting response... 200 OK Length: 295 [application/xml] <item> <created-at type="datetime">2007-02-16T04:33:00-05:00</created-at> <description>Violin treatise</description> <id type="integer">3</id> <maker>Leopold Mozart</maker> <medium>paper</medium> <modified-at type="datetime"></modified-at> <year type="integer">1744</year> </item>
The .xml on the end of the URL results in respond_to choosing the "xml" branch, and the returned document is an XML representation of the item.
respond_to and the HTTP-Accept Header
You can also trigger a branching on respond_to by setting the HTTP-Accept header in the request. When you do this, there's no need to add the .:format part of the URL.
Here's a wget example that does not use .xml but does set the Accept header:
wget http://localhost:3000/items/show/3 -O - --header="Accept: text/xml" Resolving localhost... 127.0.0.1, ::1 Connecting to localhost|127.0.0.1|:3000... connected. HTTP request sent, awaiting response... 200 OK Length: 295 [application/xml] <item> <created-at type="datetime">2007-02-16T04:33:00-05:00</created-at> <description>Violin treatise</description> <id type="integer">3</id> <maker>Leopold Mozart</maker> <medium>paper</medium> <modified-at type="datetime"></modified-at> <year type="integer">1744</year> </item>
The result is exactly the same as in the previous example.