<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Lucid &#187; simply_restful</title>
	<atom:link href="http://thelucid.com/tag/simply_restful/feed/" rel="self" type="application/rss+xml" />
	<link>http://thelucid.com</link>
	<description>The Lightweight Ramblings of Jamie Hill</description>
	<lastBuildDate>Thu, 26 Jan 2012 13:52:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Simply RESTful&#8230; &#8220;The missing action&#8221;</title>
		<link>http://thelucid.com/2006/07/26/simply-restful-the-missing-action/</link>
		<comments>http://thelucid.com/2006/07/26/simply-restful-the-missing-action/#comments</comments>
		<pubDate>Wed, 26 Jul 2006 05:25:00 +0000</pubDate>
		<dc:creator>Jamie</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Simply RESTful]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[simply_restful]]></category>

		<guid isPermaLink="false">http://16ea7a6c-c6c2-44bd-8c9c-aea8267f8ad7</guid>
		<description><![CDATA[UPDATE 15/03/10: The debate continues&#8230; The ideas in this article came about whilst I was test-driving the Simply RESTful plugin following DHH&#8217;s RailsConf keynote on the subject. The philosophy The first thing I came across whilst experimenting with Simply RESTful (which is great by the way), was that there is no real way of deleting [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE 15/03/10: <a href="http://thelucid.com/2010/03/15/rails-can-we-please-have-a-delete-action-by-default/">The debate continues&#8230;</a></strong></p>
<p>The ideas in this article came about whilst I was test-driving the <a href="http://dev.rubyonrails.org/svn/rails/plugins/simply_restful/">Simply RESTful plugin</a> following <a href="http://blog.scribestudio.com/articles/2006/07/09/david-heinemeier-hansson-railsconf-2006-keynote-address"><span class="caps">DHH</span>&#8217;s RailsConf keynote</a> on the subject.</p>
<h2>The philosophy</h2>
<p>The first thing I came across whilst experimenting with <a href="http://dev.rubyonrails.org/svn/rails/plugins/simply_restful/">Simply RESTful</a> (which is great by the way), was that there is no real way of deleting items with javascript disabled. Since I am currently working on a project that needs to function on a variety of mobile devices, this instantly caused me concern.</p>
<p>I could think of a few ways to hack around this limitation, however I was sure there had to be a better way, hence this article. I wanted to keep the current javascript functionality but in addition have a clean non-javascript fallback.</p>
<p>Consider the following:</p>
<table>
<tr>
<th>CRUD</th>
<th>Form (GET request)</th>
<th>POST action</th>
</tr>
<tr>
<td>(C)reate</td>
<td>/products/new</td>
<td>create</td>
</tr>
<tr>
<td>(R)ead</td>
<td>/products/24</td>
<td>n/a</td>
</tr>
<tr>
<td>(U)pdate</td>
<td>/products/24/edit</td>
<td>update</td>
</tr>
<tr>
<td>(D)elete</td>
<td>-</td>
<td>destroy</td>
</tr>
</table>
<p>There are three &#8220;state changing&#8221; actions in <span class="caps">CRUD</span>, they are the &#8216;create&#8217;, &#8216;update&#8217; and &#8216;delete&#8217;. You will notice from the table above that all three have a <span class="caps">POST</span> action<sup><a href="#fn1">1</a></sup>, however only two have <span class="caps">GET</span> actions&#8230; why is this?</p>
<p>Now, you see that dash in the second column&#8230; that&#8217;s &#8220;the missing action&#8221;. There is no good reason why our &#8216;destroy&#8217; action shouldn&#8217;t have a corresponding form action (GET request) also. Let me explain myself&#8230;</p>
<p style="font-size: 85%;" id="fn1"><sup>1</sup> The <span class="caps">HTTP</span> actions are <span class="caps">PUT</span>, POST and <span class="caps">DELETE</span>, however in this implementation (due to the limitations of <span class="caps">HTML</span>) they are all technically <span class="caps">POST</span>&#8217;s.</p>
<h2>Putting it into practice</h2>
<p>So we give &#8216;destroy&#8217; it&#8217;s missing action which will act as a confirmation of our post&#8230; and what shall we call this missing action? &#8230;why let&#8217;s call it delete.</p>
<p>If we fill in this missing piece in our RESTful Rails puzzle, all becomes clear:</p>
<table>
<tr>
<th><span class="caps">CRUD</span></th>
<th>Form (GET request)</th>
<th><span class="caps">POST</span> action</th>
</tr>
<tr>
<td>(C)reate</td>
<td>/products/new</td>
<td>create</td>
</tr>
<tr>
<td>(R)ead</td>
<td>/products/24</td>
<td>n/a</td>
</tr>
<tr>
<td>(U)pdate</td>
<td>/products/24/edit</td>
<td>update</td>
</tr>
<tr>
<td>(D)elete</td>
<td style="background: #ff9;">/products/24/delete</td>
<td>destroy</td>
</tr>
</table>
<p>Our routes would look something like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">map.<span style="color:#9900CC;">resource</span> <span style="color:#ff3333; font-weight:bold;">:product</span>, <span style="color:#ff3333; font-weight:bold;">:member</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:delete</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:get</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>In our controller would be:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> delete
  <span style="color:#0066ff; font-weight:bold;">@product</span> = Product.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> destroy
  Product.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">destroy</span> <span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#9900CC;">delete</span>?
  redirect_to product_url
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Our delete.rhtml would look like this:<br />
<code>
<pre>&lt;h1&gt;Are you sure you wish to delete ?&lt;/h1&gt;</pre>
<p></code></p>
<h2>Slight complication&#8230;</h2>
<p><strong>Update</strong> (13 Oct 2007): This has been fixed in more recent versions or Rails.</p>
<p><del>Now comes the slight complication&#8230; we want the javascript <span class="caps">POST</span> to /projects/24 to function as normal, however if javascript is disabled we want to request /projects/24;delete.</del></p>
<p><del>Wouldn&#8217;t it be nice if you could specify a fallback (non-javascript) href in the link_to helper, something that I&#8217;ve pondered with on many occasions. Unfortunately the link_to helper doesn&#8217;t let you override the href attribute (currently it adds a second one instead), until now.</del></p>
<p><del>Enter <a href="http://svn.soniciq.com/public/rails/plugins/iq_noscript_friendly/">iq_noscript_friendly plugin</a> which fixes this shortfall (I also have this as a Rails patch however the ticketing system on Trac is currently broken).</del></p>
<p><del>Install the plugin using:</del></p>
<pre><code>./script/plugin install http://svn.soniciq.com/public/rails/plugins/iq_noscript_friendly/</code></pre>
<p>In our listing view (index.rhtml) we are now able to do the following:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">link_to <span style="color:#996600;">'Delete'</span>, product_url<span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span>,
          <span style="color:#ff3333; font-weight:bold;">:confirm</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Are you sure?'</span>,
          <span style="color:#ff3333; font-weight:bold;">:method</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'delete'</span>,
          <span style="color:#ff3333; font-weight:bold;">:href</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> delete_product_url<span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Ideally you would just give the link a class of &#8220;delete&#8221; and use unobtrusive javascript to make it do the delete request.</p>
<p>Beautiful.</p>
<h2>Summary</h2>
<p>By adding &#8220;the missing action&#8221;, we are able to <span class="caps">POST</span> as usual (using javascript) to &#8216;destroy&#8217; but gracefully fallback to our &#8216;delete&#8217; form when javascript is not available. Besides, why shouldn&#8217;t &#8216;destroy&#8217; get it&#8217;s own form action&#8230; &#8216;create&#8217; has &#8216;new&#8217; and &#8216;update&#8217; has &#8216;edit&#8217;?</p>
<p>Now to make this whole thing even better, lets make it part of the convention. &#8216;delete&#8217; should default to <span class="caps">GET</span> and therefore negate the need for <code>:member => { :delete => :get }</code> in our routes.rb&#8230; <a href="http://www.loudthinking.com/"><span class="caps">DHH</span></a>?</p>
<p>I would love to hear peoples comments on this technique as I&#8217;m using it for everything now and it works a treat.</p>
<p>Com&#8217;on&#8230; use &#8220;the missing action&#8221;, be kind to those without javascript, and lets make it the convention!</p>
<p>Rock on RESTfulness.</p>
]]></content:encoded>
			<wfw:commentRss>http://thelucid.com/2006/07/26/simply-restful-the-missing-action/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

