<?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>Nathan's Blog &#187; ruby-on-rails</title>
	<atom:link href="http://nathan.studiodifferent.com/tag/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://nathan.studiodifferent.com</link>
	<description>Wired World Wonderings</description>
	<lastBuildDate>Mon, 22 Oct 2007 16:50:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>REST Easy, Rails 1.2 is here</title>
		<link>http://nathan.studiodifferent.com/2007/02/13/rest-easy-rails-12-is-here/</link>
		<comments>http://nathan.studiodifferent.com/2007/02/13/rest-easy-rails-12-is-here/#comments</comments>
		<pubDate>Wed, 14 Feb 2007 05:06:36 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby-on-rails]]></category>

		<guid isPermaLink="false">http://nathan.studiodifferent.com/2007/02/13/rest-easy-rails-12-is-here/</guid>
		<description><![CDATA[


Rails makes it easy to relate URL&#8217;s to their respective controller methods. If you want another action, just add the method to the controller and append the name to the controller URL. However, this controller-centric approach is a mixed blessing, because it lends itself to redundancy and extraneous methods. The recent Rails 1.2 release introduces [...]]]></description>
			<content:encoded><![CDATA[<div style="float: left; margin-right: 15px;">
<img id="image95" src="http://nathan.studiodifferent.com/wp-content/uploads/2007/02/rest-easy.jpg" alt="" />
</div>
<p>Rails makes it easy to relate URL&#8217;s to their respective controller methods. If you want another action, just add the method to the controller and append the name to the controller URL. However, this controller-centric approach is a mixed blessing, because it lends itself to redundancy and extraneous methods. The recent <a href="http://weblog.rubyonrails.org/2007/1/19/rails-1-2-rest-admiration-http-lovefest-and-utf-8-celebrations">Rails 1.2 release</a> introduces RESTful facilities and a resource-centric URL structure that makes it easier to remove the <em>junk</em> and keep the <em>CRUD</em>.<span id="more-94"></span></p>
<h3>Keep the CRUD?!</h3>
<p>CRUD refers to the four basic actions that we apply to web data: Create, Read, Update and Delete. In his 2006 <a href="http://www.scribemedia.org/2006/07/09/dhh/">RailsConf keynote</a>, David Heinemeier Hansson describes the benefits of viewing your models through the lens of CRUD, arguing that in many cases, operations beyond the basic four often just incur controller bloat. As an example, he ponders options for defining a relationship between Users and Groups. The traditional approach would be to implement the group join as <code>UsersController#join_group</code> or perhaps <code>GroupsController#add_user</code>. A third solution would be to create a new class, Memberships, that relates Users to Groups. This distills membership management to the CRUD functions &#8211; <code>MembershipsController#create</code>. While an extra model might seem to increase complexity rather than reduce it, consider the benefits of a consistent set of functions in every controller. Also recognize the ease with which we can extend Membership &mdash; <code>Membership#joined_at</code>, <code>Membership#authorized_by</code>, etc.</p>
<h3>Get some REST</h3>
<p>Roy Fielding introduced REST, or Representative State Transfer, in <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">chapter 5</a> of his 2000 dissertation. REST is basically an idealized web architecture in which <em>resources</em> (data) are manipulated through a generic interface (e.g. CRUD!) &mdash; a client can <strong>Create</strong> an User just as easily as it can <strong>Delete</strong> a Membership. In a REST architecture, messages that retrieve or alter the state of a resource are called <em>representations</em>. This abstraction offers data formats that are appropriate for each interaction &mdash; a PDA might <strong>Update</strong> inventory represented using standard HTML forms, while a PC browser might <strong>Read</strong> an XML representation of that same inventory.</p>
<h3>Enter Rails 1.2</h3>
<p>David Heinemeier Hansson describes how nicely the CRUD functions align with SQL commands and HTTP methods:</p>
<table border="1" style="margin-left: auto; margin-right: auto">
<tr>
<th></th>
<th>Create</th>
<th>Read</th>
<th>Update</th>
<th>Delete</th>
</tr>
<tr>
<th>SQL</th>
<td>INSERT</td>
<td>SELECT</td>
<td>UPDATE</td>
<td>DELETE</td>
</tr>
<tr>
<th>HTTP</th>
<td>POST</td>
<td>GET</td>
<td>PUT</td>
<td>DELETE</td>
</tr>
<tr>
<th>Rails</th>
<td>#create</td>
<td>#find</td>
<td>#update</td>
<td>#destroy</td>
</tr>
</table>
<p>Rails 1.2 takes advantage of these similarities. Compare the HTTP used to access previous &#8220;/controller/action/id&#8221; routes with the newer &#8220;/resource/id&#8221; routes:</p>
<table style="margin-left: auto; margin-right: auto">
<tr>
<th colspan="2">scaffold</th>
<th colspan="2">scaffold_resource</th>
<th>Contoller Method</th>
</tr>
<tr>
<td align="right">GET</td>
<td>/lightbulbs</td>
<td align="right">GET</td>
<td>/lightbulbs</td>
<td>#list</td>
</tr>
<tr>
<td align="right">GET</td>
<td>/lightbulbs/show/1</td>
<td align="right">GET</td>
<td>/lightbulbs/1</td>
<td>#show</td>
</tr>
<tr>
<td align="right">GET</td>
<td>/lightbulbs/edit/1</td>
<td align="right">GET</td>
<td>/lightbulbs/1;edit</td>
<td>#edit</td>
</tr>
<tr>
<td align="right">POST</td>
<td>lightbulbs/update/1</td>
<td align="right">PUT</td>
<td>/lightbulbs/1</td>
<td>#update</td>
</tr>
<tr>
<td align="right">GET</td>
<td>/lightbulbs/new</td>
<td align="right">GET</td>
<td>/lightbulbs/new</td>
<td>#new</td>
</tr>
<tr>
<td align="right">POST</td>
<td>lightbulbs/create</td>
<td align="right">POST</td>
<td>/lightbulbs</td>
<td>#create</td>
</tr>
<tr>
<td align="right">POST</td>
<td>lightbulbs/destroy/1</td>
<td align="right">DELETE</td>
<td>/lightbulbs/1</td>
<td>#destroy</td>
</tr>
</table>
<p>Notice how traditional routes include the action in the URL, and use only GET and POST. The RESTful URL&#8217;s refer to resources, and the controller infers the action from the HTTP method and headers. In what Hansson calls an HTTP &#8220;renaissance&#8221;, Rails 1.2 now embraces PUT and DELETE, and acknowledges a client&#8217;s &#8220;Accept&#8221; and &#8220;Content-Type&#8221; headers. Unfortunately web browsers don&#8217;t support PUT or DELETE, but Rails emulates them through a POST with the hidden variable &#8220;_method&#8221;.</p>
<p>Rails&#8217; new RESTful scaffold generator (<code>script/generate scaffold_resource</code>) is a good place to get started with the new facilities. When run without any arguments, the new generator gives a basic overview of it&#8217;s usage.</p>
<h3>Just the beginning&#8230;</h3>
<p>Pretty URL&#8217;s and uniform controller methods barely scratch the surface of the benefits imparted by REST. Consider the potential use of a generic HTTP interface as a <a href="http://blog.whatfettle.com/2007/01/11/good-web-apis-are-just-web-sites/">simple web API</a>. The prospect of being unencumbered by the complexity of SOAP opens the doors for use with AJAX and in simple scripts. Fielding&#8217;s <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">dissertation</a> goes on to describe the caching and scaling benefits of a pure REST architecture.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathan.studiodifferent.com/2007/02/13/rest-easy-rails-12-is-here/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails Page Caching Explained</title>
		<link>http://nathan.studiodifferent.com/2006/12/02/rails-page-caching-explained/</link>
		<comments>http://nathan.studiodifferent.com/2006/12/02/rails-page-caching-explained/#comments</comments>
		<pubDate>Sat, 02 Dec 2006 20:54:36 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby-on-rails]]></category>

		<guid isPermaLink="false">http://nathan.studiodifferent.com/2006/12/02/rails-page-caching-explained/</guid>
		<description><![CDATA[


Page caching is the simplest form of caching that Ruby on Rails offers. When invoked, page caching saves output to Rails&#8217; public directory where it is subsequently served along with the other static pages. Of course this is advantageous for high traffic sites or pages that are slow to render. In most cases, page caching [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; margin-left: 15px;">
<img id="image75" src="http://nathan.studiodifferent.com/wp-content/uploads/2006/12/cache.png" alt="cache.png" />
</div>
<p>Page caching is the simplest form of caching that Ruby on Rails offers. When invoked, page caching saves output to Rails&#8217; public directory where it is subsequently served along with the other static pages. Of course this is advantageous for high traffic sites or pages that are slow to render. In most cases, page caching works without any config file editing. I, however, encountered a minor problem that prompted me to investigate this simple mechanism a bit further.<span id="more-74"></span></p>
<h3>Rails Configuration</h3>
<p>Just add one line to a controller to enable page caching:</p>
<pre>class DemoController &lt; ApplicationController
  caches_page :show</pre>
<p>The <a href="http://api.rubyonrails.org/classes/ActionController/Caching/Pages/ClassMethods.html#M000091">caches_page()</a> method instructs Rails to cache the output of the indicated actions. In the above example, Rails will save the output generated by the <strong>show</strong> action to the corresponding public directory. For example if a browser visits http://server/demo/show/123, cached output will reside in the file public/demo/show/123.html. For future requests, the web server will use this static file rather than running any Rails code.</p>
<p>If you would like Rails to expire the page, the easiest option is to call the method <a href="http://api.rubyonrails.org/classes/ActionController/Caching/Pages.html#M000087">expire_page()</a>. Arguments follow the same syntax as <a href="http://api.rubyonrails.org/classes/ActionController/Base.html#M000202">url_for</a>. Under the hood, page expiry simply deletes the cached file. To expire the file created in the previous paragraph: <code>expire_page :controller =&gt; "demo", :action =&gt;, :id =&gt; 123</code></p>
<p>By default, caching directives are ignored unless RAILS_ENV=&#8221;production&#8221;. You can explicitly control caching for each environment by specifying <code>config.action_controller.perform_caching = true</code> in the appropriate environment file (e.g. &#8220;config/environments/development.rb&#8221;).</p>
<h3>Web Server Configuration</h3>
<p>Notice that Rails appends an &#8220;html&#8221; extension to cached pages. This extension allows the web server to treat the file like any other HTML file for determination of MIME type, permissions, etc. However, the extension also means that the web server must be configured to internally append &#8220;.html&#8221; to serve the cached page. Rails&#8217; skeleton directory includes an Apache configuration file (public/.htaccess), and a Lighttpd configuration (config/lighttpd.conf), which do just that:</p>
<table>
<thead>
<tr>
<th width="50%">Apache</th>
<th width="50%">Lighttpd</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top">
<pre>
RewriteEngine On
RewriteRule ^([^.]+)$ $1.html [QSA]
</pre>
</td>
<td valign="top">
<pre>
server.modules = ( "mod_rewrite", ... )
url.rewrite += ( "^([^.]+)$" =&gt; "$1.html" )
</pre>
</td>
</tr>
</tbody>
</table>
<p>Notice the regular expression common to both configurations: <code>^([^.]+)$</code>. In English this translates to &#8220;if a request does not contain a period: <code>^([^.]+)$</code>, then internally append &#8216;.html&#8217; to that request: <code>$1.html</code>&#8220;.</p>
<h3>My Original Problem: Firefox Ignoring Updates</h3>
<p>I encountered what may be an isolated issue wherein Firefox 2 consistently failed to update pages whose contents expired via expire_page(). &#8220;about:cache&#8221; revealed that FireFox was setting a brief expiration time on static pages, and was using the old cached copy rather than requesting the current server copy. The workaround was easy enough &#8211; tell the web server to immediately expire cached pages. Continuing the above example, the Apache config should reside in public/demo/.htaccess, and the Lighttpd config should be added to lighttpd.conf:</p>
<table>
<thead>
<tr>
<th width="50%">Apache</th>
<th width="50%">Lighttpd</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top">
<pre>
ExpiresActive On
ExpiresDefault Now
</pre>
</td>
<td valign="top">
<pre>
server.modules = ( "mod_expire", ... )
$HTTP["url"] =~ "^/demo" {
  expire.url = ( "" =&gt; "access 0 seconds" )
}
</pre>
</td>
</tr>
</tbody>
</table>
<p>These directives cause the web server to append <strong>Expires</strong> (HTTP 1.0) or <strong>Cache-Control</strong> (HTTP 1.1) headers that instruct the client to request the page anew for each display. This is less bandwidth-efficient, but that was not an issue for the intranet site I was working on.</p>
]]></content:encoded>
			<wfw:commentRss>http://nathan.studiodifferent.com/2006/12/02/rails-page-caching-explained/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
