Home > Articles > Programming > Ruby

  • Print
  • + Share This
This chapter is from the book

This chapter is from the book

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.

  • + Share This
  • 🔖 Save To Your Account