Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1
RESTful Rails | 217

Although this uses JavaScript to accomplish its primary action, it is still safe (though
nonfunctional) in browsers that do not support JavaScript. Those browsers will
ignore theonclickaction, instead treating the link as a standardGETlink. If the link is
clicked, the browser will sendGET /people/1, which will harmlessly call theshow
action on that person.


Note that we would not want to fall back to an action that actually calls ourdelete
method, because it is behind a standard HTML link (once the JavaScript is stripped
out). As theGETaction is presumed to be idempotent and safe, proxy caches and user
agents would be permitted to prefetch our link without the user’s request. This is the
same problem that caused the Google Web Accelerator issues discussed earlier. But
the advantage of RESTful design is that we could not name thedeleteaction by URI
alone if we wanted to; it requires the resource’s URI in conjunction with theDELETE
HTTP method, and all of the semantics involved therein.


In applications where non-JavaScript-aware browsers need to be fully
supported, you should use other helpers such asbutton_toor the stan-
dard form helpers. These create HTML constructs with the proper
semantics; even user agents that do not support JavaScript respect that
<button>or<form>tags are unsafe and should not be followed with-
out the user’s interaction.

Method emulation


REST is designed to use a full set of HTT Pmethods, which at a minimum include
GET,PUT,POST,HEAD, andDELETE. Unfortunately, there are a few roadblocks to using
these directly. HTML 4 only supportsGETandPOSTas form methods, and of course
standard HTML links only request documents viaGET(by design). In addition, many
proxies, caches, and other intermediaries often only supportGETandPOST, as the
other methods were not in wide use on the Web for many years.


To work around this problem, Rails uses a small hack. Methods other thanGETor
POSTare sent asPOST(the catch-all method as it is neither required to be safe nor
idempotent). To allow the server to determine the original method, it is stored in a
POSTvariable called_method. The Prototype JavaScript library works in the same way
when calling an action viaAjax.RequestorAjax.Updaterwith a method other than
GET orPOST.


Content Types


The idea that one resource can have multiple representations in different content
types is one of the core principles of REST. It recognizes that different representa-
tions of one thing, whether formatted as JavaScript, HTML, XML, ICS, or in any
other format, is fundamentally the same resource. Rails has introduced rich support
for rendering different responses based on the content type the client wants, via the
respond_to method.

Free download pdf