<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
  <title>The Rails Way - Home</title>
  <id>tag:www.therailsway.com,2009:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  
  <link href="http://www.therailsway.com/" rel="alternate" type="text/html" />
  <updated>2009-06-22T10:00:04Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/TheRailsWay" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-06-22:20922</id>
    <published>2009-06-22T06:13:00Z</published>
    <updated>2009-06-22T10:00:04Z</updated>
    <category term="rest" />
    <category term="too far" />
    <link href="http://www.therailsway.com/2009/6/22/taking-things-too-far-rest" rel="alternate" type="text/html" />
    <title>Taking Things Too Far: REST</title>
<content type="html">
            &lt;p&gt;&lt;i&gt;I’m going to put up a few posts based on a talk I gave at RailsConf ‘09 in Vegas and RailsWayCon in Berlin.    Sorry for the delay in updating but I wanted to deliver the talks before posting here.&lt;/i&gt;&lt;/p&gt;


	&lt;p&gt;There’s a common pattern I see when working on code-reviews with &lt;a href="http://www.actionrails.com"&gt;ActionRails&lt;/a&gt; or my consulting work.  People find a new technique, technology or idea and put it to work in their projects.  At first they get a huge benefit, problems get solved quickly and things are good.  Driven by this initial success they double down, they put their new tool to work in more areas of their application, they even go back over their old stuff and seek out more pure ways to apply it.&lt;/p&gt;


	&lt;p&gt;However as time passes they find the benefits aren’t quite what they used to be.  Their nice new toy has turned into something which they find gets in the way on a regular basis.  Eventually they ‘throw that shit out’.  Part of this is just the natural progression of technology, something better comes along and we adopt it.  But another part of it is our tendency to over do things.  The technology we picked up isn’t shit,  the promise we saw was real.  But we’ve taken it beyond its intended use, learned the wrong lessons and tied ourselves up as a result.&lt;/p&gt;


	&lt;p&gt;I’m going to cover a few techniques used in the Rails community which are great, but which turn on you if you take them too far.  Starting with RESTful design.&lt;/p&gt;


	&lt;h2&gt; Restful Design&lt;/h2&gt;


	&lt;p&gt;RESTful design really started catching on with Rails 1.2, and by the time 2.0 was released it had become something approaching &lt;a href="http://en.wikipedia.org/wiki/Canon_law"&gt;Canon Law&lt;/a&gt;.  Everyone who was anyone and building a Rails application, was focussing on resources, &lt;span class="caps"&gt;CRUD&lt;/span&gt; and &lt;span class="caps"&gt;HTTP&lt;/span&gt;.  There were two chief benefits of this change.&lt;/p&gt;


	&lt;p&gt;The first benefit, and the one everyone focussed on, was that you had a relatively straightforward way to add an &lt;span class="caps"&gt;API&lt;/span&gt; to your application.  Back in the preREST dark-ages everyone who was designing an &lt;span class="caps"&gt;API&lt;/span&gt; for their application had to make a bunch of decisions about how they wanted to build it.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Do you re-use your controllers, or have a separate &lt;ins&gt;ApiController&lt;/ins&gt;?&lt;/li&gt;
		&lt;li&gt;How do you pass arguments around?&lt;/li&gt;
		&lt;li&gt;What should the URLs look like?&lt;/li&gt;
		&lt;li&gt;Perhaps &lt;span class="caps"&gt;XML&lt;/span&gt;-RPC or &lt;span class="caps"&gt;SOAP&lt;/span&gt; is the right way?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;With &lt;span class="caps"&gt;REST&lt;/span&gt; you get answers to all those questions, and instead of worrying about that, you just get on with building your Application.&lt;/p&gt;


	&lt;p&gt;Even for applications without an &lt;span class="caps"&gt;API&lt;/span&gt;, REST gives you some benefits.  You avoid discussions about what your controllers and actions should be called, and what your  URLs should look like.   It also makes it easier for new developers to get up to speed with your project.  Almost every rails developer now knows that if you’re looking for the thing which creates posts, you’ll be looking at &lt;ins&gt;PostsController#create&lt;/ins&gt;.&lt;/p&gt;


	&lt;h3&gt;Taking it Further&lt;/h3&gt;


	&lt;p&gt;If we look at a slightly more complicated example, we can see the beginnings of the friction that comes from taking things too far.  Take an example of a site which lets people upload photos and write blog posts, and lets users comment on one another’s data.  The most common way to approach this design would be:&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
  map.resources :bookmarks, :has_many =&amp;gt; [:comments]
  map.resources :posts,     :has_many =&amp;gt; [:comments]
&lt;/pre&gt;

	&lt;p&gt;The nice thing about this design is that the URLs will reflect the underlying structure of the data you’re managing.  For example the &lt;span class="caps"&gt;URL&lt;/span&gt; for comments on post number 5 will be &lt;ins&gt;/posts/5/comments&lt;/ins&gt; and for bookmark 3 will be &lt;ins&gt;/bookmarks/3/comments&lt;/ins&gt;.  However where it starts to get a /little/ annoying is when you want to do something generic to all comments, like providing a ‘mark as spam’ link alongside a comment.  Because comments exist solely as a child of the &lt;ins&gt;Commentable&lt;/ins&gt; we can’t generate the URLs without knowing the class and id of that object.  So it’s just that little bit more difficult to deal with comments generically (e.g. in an admin interface).  This tends to lead to you writing a helper something like this:&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
  def spam_comment_url(comment)
    case o = comment.commentable
      when Post
        spam_post_comment_url(o, comment)
      when Bookmark
        spam_bookmark_comment_url(o, comment)
      end
    end
  end
&lt;/pre&gt;

	&lt;p&gt;Now this is a good indicator that you should probably also have a top-level resource for your comments, and thankfully there’s a feature for this case which gives you a nice pragmatic way out.&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
  # First define the top-level comment resource
  map.resources :comments, :member =&amp;gt; {:spam=&amp;gt;:post}

  # then add a shallow collection under each of the commentables
  map.resources :bookmarks do |bookmarks|
    bookmarks.resources :comments, :shallow=&amp;gt;true
  end

  map.resources :posts do |posts|
    posts.resources :comments, :shallow=&amp;gt;true
  end
&lt;/pre&gt;

	&lt;h3&gt;Taking it Too Far&lt;/h3&gt;


	&lt;p&gt;Unfortunately people often get started with &lt;span class="caps"&gt;REST&lt;/span&gt; and love the way it simplifies their designs and gives them conventions to follow.  They then take their new rose coloured glasses and start making sure everything in their app is “purely RESTful”.  Every new design decision &lt;strong&gt;must&lt;/strong&gt; be perfectly RESTful, anything which looks like &lt;span class="caps"&gt;RPC&lt;/span&gt; is instantly purged from the application.&lt;/p&gt;


	&lt;p&gt;Taking this more extreme approach to the problem of marking comments as spam they’ll say something like:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;When you think about it,  marking a comment as spam is really &lt;strong&gt;creating&lt;/strong&gt; the &lt;ins&gt;SpamScore&lt;/ins&gt; child resource of the comment with the value of &lt;ins&gt;spam&lt;/ins&gt; set to &lt;ins&gt;true&lt;/ins&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;And build something like this, so when they want to mark a comment as spam they ‘only’ have to construct a &lt;span class="caps"&gt;POST&lt;/span&gt; request to the &lt;ins&gt;bookmark_comment_spam_score_url&lt;/ins&gt; of &lt;ins&gt;/posts/1/comments/2/spam_score&lt;/ins&gt;:&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
  map.resources :bookmarks do |bookmarks|
    bookmarks.resources :comments do |bookmark_comments|
      bookmark_comments.resource :spam_score
    end
  end
&lt;/pre&gt;

	&lt;p&gt;While this may be purely restful, it’s much more complicated than the ‘impure’ &lt;span class="caps"&gt;RPC&lt;/span&gt; approach taken above with a simple &lt;span class="caps"&gt;URL&lt;/span&gt; like &lt;ins&gt;/comments/1/spam&lt;/ins&gt;.  Plus if you want to get truly pure your URLs should probably be more like this:&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
map.resources :users do |users|
  users.resources :bookmarks do |bookmarks|
    bookmarks.resources :comments do |bookmark_comments|
      bookmark_comments.resource :spam_score
    end
  end
end
&lt;/pre&gt;

	&lt;p&gt;The advice I typically give when I come across a “complex but pure” model like this is to go back to basics and remember why we originally started using &lt;span class="caps"&gt;REST&lt;/span&gt;.  Does it help us make an &lt;span class="caps"&gt;API&lt;/span&gt;? Does it make things simpler for new developers to follow?  Does it make it easier to work with some of the great plugins out there?  If the answer to all those questions is no, you should probably dial back the purity and do the pragmatic thing.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-06-22:20924</id>
    <published>2009-06-22T06:08:00Z</published>
    <updated>2009-06-22T06:08:54Z</updated>
    <link href="http://www.therailsway.com/2009/6/22/updates" rel="alternate" type="text/html" />
    <title>Updates</title>
<content type="html">
            &lt;p&gt;Just a few quick updates about what’s going on around here.&lt;/p&gt;


	&lt;h3&gt;Sponsorship&lt;/h3&gt;


	&lt;p&gt;New Relic have generously been sponsoring this site for a few months now.  I’ve been a user of their &lt;span class="caps"&gt;RPM&lt;/span&gt; product for a while now and recommend it to all my clients, so when they offered to sponsor the site I was happy to accept.  In addition to the product, they also have some interesting stuff on their performance focussed site &lt;a href="http://railslab.newrelic.com"&gt;RailsLab&lt;/a&gt; site.  I don’t intend to talk about anything related to their products or services here, but in case I secretly turn into a shill, this counts as full disclosure.&lt;/p&gt;


	&lt;h3&gt;Comments Policy&lt;/h3&gt;


	&lt;p&gt;A few comments have been less-than-friendly to either myself, or other commenters.  So my new comment policy is &lt;strong&gt;Be civil&lt;/strong&gt;.  Feel free to disagree with any posts or comments here, but do so civilly.  Anything which violates this new policy will just be deleted without comment. However life’s too short to spend time moderating comments, so let’s all just be nice.&lt;/p&gt;


	&lt;h3&gt; Action Rails&lt;/h3&gt;


	&lt;p&gt;I’ve teamed up with Pratik Naik and Mike Gunderloy to form Action Rails.  We provide a number of services which could be of interest to readers here.  If you want your application’s code and architecture reviewed by a team of experts, ongoing support for your development team or help with a one-off specific problem we can help.  For more information see the details at &lt;a href="http://www.actionrails.com/"&gt;ActionRails.com&lt;/a&gt; or email &lt;a href="mailto:sales@actionrails.com"&gt;sales@actionrails.com&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-04-23:11276</id>
    <published>2009-04-23T23:46:00Z</published>
    <updated>2009-04-24T00:04:10Z</updated>
    <category term="files" />
    <category term="porter" />
    <category term="uploads" />
    <link href="http://www.therailsway.com/2009/4/23/uploading-files" rel="alternate" type="text/html" />
    <title>Uploading Files</title>
<content type="html">
            &lt;p&gt;Anyone who’s built a rails application that deals with large file uploads probably has a few horror stories to tell about it.  While some people love to overstate the issues for their own purposes, it’s still something that can be quite challenging to do well.&lt;/p&gt;


	&lt;h2&gt;What’s the Problem?&lt;/h2&gt;


	&lt;p&gt;As I mentioned in the article on File Downloads, your rails processes are a scarce resource.  You need them to be free to handle your applications’ requests, if they’re all busy, your users will be left waiting.  When we optimised the download processes we made sure that we used our webservers instead of tying up a rails process to spoon feed the file out over the network to your users.  Dealing with uploads has a similar problem.&lt;/p&gt;


	&lt;p&gt;When a browser uploads a file, it encodes the contents in a format called ‘multipart mime’ (it’s the same format that gets used when you send an email attachment).  In order for your application to do something with that file, rails has to undo this encoding.  To do this requires reading the huge request body, and matching each line against a few regular expressions.  This can be incredibly slow and use a huge amount of &lt;span class="caps"&gt;CPU&lt;/span&gt; and memory.&lt;/p&gt;


	&lt;p&gt;While this parsing is happening your rails process is busy, and can’t handle other requests.  Pity the poor user stuck behind a request which contains a 100M upload!&lt;/p&gt;


	&lt;h2&gt;What’s &lt;strong&gt;not&lt;/strong&gt; the problem?&lt;/h2&gt;


	&lt;p&gt;Some people seem to think that the File Upload problem with rails is that the entire process is blocked while the browser &lt;strong&gt;sends&lt;/strong&gt; the encoded body to you.  This isn’t not true, and hasn’t been for a long time. Whether you’re using nginx + mongrel, apache + mongrel or apache + passenger, your web server buffers the entire request before rails locks itself for processing.  So no matter how slow a user’s connection is, your application isn’t locked while they upload their file.&lt;/p&gt;


	&lt;h2&gt;What can you do?&lt;/h2&gt;


	&lt;p&gt;There are a number of unattractive options to work around this slow multipart-parsing.  The most common I’ve seen is to send uploads to a non-rails process such as a &lt;span class="caps"&gt;CGI&lt;/span&gt; script or a merb/mongrel/rack application.  &lt;span class="caps"&gt;CGI&lt;/span&gt; scripts have the obvious disadvantage that you need to write a script simple enough to start up quickly and featured enough to process your uploads.  Doing it in rack leaves you relying on ruby’s threading to handle parallelism.  &lt;a href="http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/"&gt;This is probably not what you want&lt;/a&gt; and your throughput is probably much lower than it would be without that upload being processed.&lt;/p&gt;


	&lt;h2&gt;What else can you do?&lt;/h2&gt;


	&lt;p&gt;Because neither of these options were acceptable Pratik Naik and I have built a &lt;a href="http://modporter.com/"&gt;Mod Porter&lt;/a&gt; an Apache module that does the heavy lifting for your file uploads. All of the hard stuff is done by &lt;a href="http://httpd.apache.org/apreq/"&gt;libapreq&lt;/a&gt; though, so you don’t have to worry about using C code written by two ruby programmers!&lt;/p&gt;


	&lt;p&gt;Porter is essentially the inverse of X-SendFile.  It parses the multipart post in C inside your apache process and writes the files to disk.  Once that work is done it changes the request to look like a regular form &lt;span class="caps"&gt;POST&lt;/span&gt; which contains pointers to the temp files on disk.  To maintain system security it also signs the modified parameters so people can’t attack your system like those old &lt;span class="caps"&gt;PHP&lt;/span&gt; apps.&lt;/p&gt;


	&lt;p&gt;This means that your rails processes don’t have to deal with anything more than a regular form post which is nice and fast. In addition to the apache module, Porter also includes a Rails Plugin which hides all of this from you.  It makes an upload handled by Porter, look just like a regular Rails Upload.&lt;/p&gt;


	&lt;h2&gt;How fast is it?&lt;/h2&gt;


	&lt;p&gt;The speed of upload parsing isn’t particularly relevant, the reduced locking is far more important.  Your user’s internet connection is much more important for the round-trip upload performance than your upload handler’s parser.&lt;/p&gt;


	&lt;p&gt;Having said all that, Porter runs &lt;strong&gt;significantly&lt;/strong&gt; faster than the equivalent pure-ruby parsing code.  Depending on the size and number of uploads we’ve seen response times between 30 and 200 times as fast.  That’s not just compared to rails’ upload parser, it’s that much faster than every other ruby mime parser we tried.&lt;/p&gt;


	&lt;h2&gt;Isn’t this just like the Nginx module?&lt;/h2&gt;


	&lt;p&gt;Kinda.  We’ve been thinking about this module ever since we started using lighttpd’s X-SendFile header.  When I saw the nginx module get released I decided to start planning the Apache equivalent. Porter is completely transparent to your application, you don’t need a special form action, and you don’t need to tell Porter what form fields to pass through to the web application.  This means you can use porter in production, and mongrel or thin in development, without any changes to your application.&lt;/p&gt;


	&lt;p&gt;The biggest improvement from this is that you don’t need to change your nginx config every time you add a new input to a form, or a new file upload to your application.  This is extremely tedious and error prone, especially when making these changes involves a support ticket with your hosting provider.  The major goal we have with Porter is to make sure it always ‘Just Works’, so you can put a file upload into any form without having to worry about your web server.&lt;/p&gt;


	&lt;h2&gt;Getting Started&lt;/h2&gt;


	&lt;p&gt;Porter is still beta software, so you’re &lt;strong&gt;strongly&lt;/strong&gt; advised to test it first, but you already knew that.   The porter website has the &lt;a href="http://modporter.com/install.html"&gt;installation instructions&lt;/a&gt;.  Once you’ve got that done you’ll need to add the rails plugin, and configure them to share a nice secure secret.  Then, hopefully, your application will Just Work but your uploads will be much less painful.&lt;/p&gt;


	&lt;p&gt;If you have any issues getting it running, leave us a note on the &lt;a href="http://github.com/actionrails/modporter/issues"&gt;git hub issues page&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-04-06:14702</id>
    <published>2009-04-06T23:20:00Z</published>
    <updated>2009-04-06T23:21:52Z</updated>
    <category term="dry" />
    <category term="inheritance" />
    <link href="http://www.therailsway.com/2009/4/6/controller-inheritance" rel="alternate" type="text/html" />
    <title>Controller Inheritance</title>
<content type="html">
            &lt;p&gt;Just a brief interlude from the File Management series while I sort out some time to do some benchmarking.&lt;/p&gt;


	&lt;p&gt;A common pattern I see in submissions and client-applications is repetitive declarations in controllers.  There’s a neat and simple solution for this, but given how often  Things like this:&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
  class TodoController &amp;lt; ApplicationController
    before_filter :login_required
    before_filter :handle_iphone_support
    before_filter :fetch_todo
    around_filter :performance_logging

    def index
    ...
    end
  end
&lt;/pre&gt;
For a single controller this set of declarations wouldn’t be a problem, but the problem is when all those declarations end up duplicated in several different controllers.  Thankfully every controller inherits from ApplicationController so we can do something like this:

&lt;pre class="sh_ruby"&gt;
  class ApplicationController &amp;lt; ActionController::Base
    before_filter :login_required
    before_filter :handle_iphone_support
    around_filter :performance_logging

  end

  class TodoController &amp;lt; ApplicationController
    before_filter :fetch_todo

    def index
    ...
    end
  end
&lt;/pre&gt;

	&lt;p&gt;This is easy, and obvious and most people do that.  However what do you do when you have several controllers which don’t need the login_required call?  One option is to give up on inheritance and go back to copying-and-pasting the filter declarations.  Another option is to selectively opt-out of the parent controller’s filters.&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
  class ApplicationController &amp;lt; ActionController::Base
    before_filter :login_required
    before_filter :handle_iphone_support
    around_filter :performance_logging
  end

  class SignupController &amp;lt; ApplicationController
    skip_before_filter :login_required
  end
&lt;/pre&gt;

	&lt;p&gt;However if you have several controllers which don’t require logins, you’ll find yourself duplicating the skip_before_filter declarations around.  Otherwise filters and declarations which aren’t completely universal still.  An approach which solves this nicely is to introduce an abstract parent controller for all your authenticated controllers.&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
  class ApplicationController &amp;lt; ActionController::Base
    before_filter :handle_iphone_support
    around_filter :performance_logging
  end

  class AuthenticatedController &amp;lt; ApplicationController
    before_filter :login_required
  end 

  class TodoController &amp;lt; AuthenticatedController
    before_filter :fetch_todo

    def index
    ...
    end
  end
&lt;/pre&gt;

	&lt;p&gt;This technique doesn’t just work with filter declarations most other declarations such as caching, session and csrf options work as expected too.  In addition you can introduce several parent classes as needed such as a PublicController with page caching declarations, an AdminController for your admin panels etc.  Inheritance isn’t the solution to every case of duplicate declarations, yet it’s a simple technique that can simplify most uses.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-03-16:12442</id>
    <published>2009-03-16T03:51:00Z</published>
    <updated>2009-03-16T03:58:52Z</updated>
    <category term="files" />
    <category term="nfs" />
    <category term="s3" />
    <category term="uploads" />
    <link href="http://www.therailsway.com/2009/3/16/storing-your-files" rel="alternate" type="text/html" />
    <title>Storing Your Files</title>
<content type="html">
            &lt;p&gt;This is the second article in my series on file management, the third article will cover the challenges of handling uploads then we should be able to move on to some more advanced topics.&lt;/p&gt;


	&lt;p&gt;The second problem you’ll face when building an application to handle files is where and how to store them.  Thankfully there are lots of well-supported options, each with their own pros and cons.&lt;/p&gt;


	&lt;h2&gt;The local file system&lt;/h2&gt;


	&lt;p&gt;If your application only runs on a single server, the simplest option is to store them on the local disk of your web/application server.  This leaves you with very few moving parts, and you know that both your rails application and your webserver can see the same files, at the same location.  But even though this is a simple option there are a few things that you need to be careful of.&lt;/p&gt;


	&lt;p&gt;A common mistake I see is to use a single directory to handle all of the users’ uploaded files.  So your directory structure ends up looking something like this:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;/home/railsway/uploads/koz_avatar.png
/home/railsway/uploads/dhh_avatar.png
/home/railsway/uploads/other_avatar.png&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;The first, and most obvious, problem with this structure is that unless you’re careful you could end up with users overwriting each other’s files.  The second, and more painful problem is that you end up with &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=directory+too+many+files&amp;amp;btnG=Search"&gt;too many files in a single directory&lt;/a&gt; which will cause you some pain when you try to do things like list the directory or start removing old files.&lt;/p&gt;


	&lt;p&gt;The best bet is to store the uploads in a directory which corresponds to the ID of the object which owns those files.  But something like the following will also leave you with a huge directory:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;/home/railsway/uploads/1/koz_avatar.png
/home/railsway/uploads/2/dhh_avatar.png
/home/railsway/uploads/3/other_avatar.png&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;The best bet is to partition that directory into a number of sub directories like this:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;/home/railsway/uploads/000/000/001/koz_avatar.png
/home/railsway/uploads/000/000/002/dhh_avatar.png
/home/railsway/uploads/000/000/003/other_avatar.png&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Thankfully both of the popular file management plugins have built in support for partitioned storage &lt;a href="http://giantrobots.thoughtbot.com/2008/3/18/for-attaching-files-use-paperclip#comment--614066248"&gt;:id_partition in paper clip&lt;/a&gt; and &lt;a href="http://github.com/technoweenie/attachment_fu/blob/ab1e4f7b0b9de85e0c9decf061d2ef5c1dc0feaa/README#L47"&gt;:partition in attachment_fu&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;&lt;span class="caps"&gt;NFS&lt;/span&gt;, GFS and friends&lt;/h2&gt;


	&lt;p&gt;Once you’ve grown beyond a single app / web server, using the file-system gets a little more complicated.  In order to ensure that all your app and web servers can see the same files you have to use a shared file system of some sort.  Setting up and running a shared file system is beyond the scope of this site, but a few words of caution.&lt;/p&gt;


	&lt;p&gt;It’s deceptively easy to set up a simple &lt;span class="caps"&gt;NFS&lt;/span&gt; server for your network and just run your application as you did when it was on a single disk, but some things which are cheap on local disk are slow and expensive over &lt;span class="caps"&gt;NFS&lt;/span&gt; and friends.  Make sure you stress test your file server and pay an expert to help you tune the system.  The bigger problem I’ve had with &lt;span class="caps"&gt;NFS&lt;/span&gt; and &lt;span class="caps"&gt;GFS&lt;/span&gt; is the impact of downtime or difficulties on your application.  Your &lt;span class="caps"&gt;NFS&lt;/span&gt; server becomes a single point of failure for your whole site, and a minor network glitch can render your application completely useless as all the processes get tied up waiting on a blocking read from an &lt;span class="caps"&gt;NFS&lt;/span&gt; mount that’s gone away.&lt;/p&gt;


	&lt;p&gt;You can solve all those kinds of problems by hiring a good sysadmin and / or spending a large amount of money on &lt;a href="http://en.wikipedia.org/wiki/NetApp_Filer"&gt;serious&lt;/a&gt; &lt;a href="http://www.bluearc.com/html/products/titan-1100.shtml"&gt;storage hardware&lt;/a&gt;.  It’s not a path that I personally choose, but it’s definitely an option you should consider.&lt;/p&gt;


	&lt;h2&gt; Amazon S3&lt;/h2&gt;


	&lt;p&gt;It’s not really possible to write about storage without touching on &lt;a href="http://aws.amazon.com/s3/"&gt;Amazon S3&lt;/a&gt;.  In case you’ve been living under a rock for a few years S3 is a &lt;a href="http://aws.amazon.com/s3/#principles"&gt;hugely scalable&lt;/a&gt;, &lt;a href="http://aws.amazon.com/s3/#pricing"&gt;incredibly cheap&lt;/a&gt; storage service.  There are &lt;a href="http://amazon.rubyforge.org"&gt;several&lt;/a&gt; &lt;a href="http://rightscale.rubyforge.org/right_aws_gem_doc/"&gt;good gems&lt;/a&gt; to use with your applications and the major file management plugins provide semi-transparent S3 support.&lt;/p&gt;


	&lt;p&gt;S3 isn’t a file system so there are several things which you have to do differently, however there are alternatives for most of those operations.  For instance instead of using  &lt;a href="http://www.therailsway.com/2009/2/22/file-downloads-done-right"&gt;X-Sendfile&lt;/a&gt; to stream the files to your user, you redirect them to the signed url on amazon’s own service.  By way of example our download action from the earlier article would look like this if using S3 and &lt;a href="http://amazon.rubyforge.org/"&gt;marcel’s s3 library&lt;/a&gt; &lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;def download
  redirect_to S3Object.url_for('download.zip',
                               'railswayexample',
                               :expires_in =&amp;gt; 3.hours)
end&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;But there are a few things you have to be careful with when using S3.  The first is that uploading to s3 is &lt;strong&gt;much&lt;/strong&gt; slower than simply writing your file to local disk. Unless you want your rails processes to be tied up for ages, you’ll probably want to have a background job running which transfers the files from your server up to amazon’s.  Another factor is that when S3 errors occur your users will be greeted by a very ugly error page:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Finally there’s always the risk of amazon having another &lt;a href="http://www.readwriteweb.com/archives/more_amazon_s3_downtime.php"&gt;bad day&lt;/a&gt; which takes your application down for a few hours.  Amazon’s engineers are pretty amazing, but nothing’s perfect.&lt;/p&gt;


	&lt;h2&gt;Other options&lt;/h2&gt;


	&lt;p&gt;There are a few options I’ve not used before, but you could investigate:&lt;/p&gt;


	&lt;h3&gt;BLOBs in your database&lt;/h3&gt;


	&lt;p&gt;I’ve never been a fan of using BLOBs to store large files, however some people swear by them.  If you’re aware of great tutorial resources for BLOBs and rails, let me know and I’ll link to them from here.&lt;/p&gt;


	&lt;h3&gt;Rackspace’s Cloud Files&lt;/h3&gt;


	&lt;p&gt;When it was first announced &lt;a href="http://www.mosso.com/cloudfiles.jsp"&gt;Cloud Files&lt;/a&gt; from rackspace seemed like it was going to be a great competitor to S3.  However there’s currently no equivalent to S3’s signed-url authentication option which means downloads become &lt;strong&gt;much&lt;/strong&gt; harder.  To use Cloud Files would require you to build a streaming proxy in your application, and use it to stream files from rackspace back out to the user.  You’d also have to pay for the bandwidth twice, once from rackspace, and once from your hosting provider.&lt;/p&gt;


	&lt;p&gt;This makes it &lt;strong&gt;much&lt;/strong&gt; more complicated than S3 but hopefully this will be addressed in a future release.&lt;/p&gt;


	&lt;h3&gt;MogileFS&lt;/h3&gt;


	&lt;p&gt;&lt;a href="http://www.danga.com/mogilefs/"&gt;MogileFS&lt;/a&gt; is a really interesting option.  It has some similarities to S3 in that it’s a write-once file storage system which operates over &lt;span class="caps"&gt;HTTP&lt;/span&gt;.  But unlike S3 it’s open source software you can run on your own servers.  Unfortunately MogileFS is really thinly documented and quite difficult to get up and running.  If you know of a really good getting-started tutorial for MogileFS, let me know and I’ll link to it from here.&lt;/p&gt;


	&lt;p&gt;It also would require you to use perlbal for your load balancer or find an apache module that can support X-Reproxy-Url.&lt;/p&gt;


	&lt;h2&gt; Conclusion&lt;/h2&gt;


	&lt;p&gt;There are a bunch of different options you should consider when picking the storage for your file uploads.  Generally my advice would be to start with simple on-disk partitioned storage and grow from there.  Don’t rush straight to S3 because all the blogs tell you to, stay as simple as possible for as long you can.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-02-22:11275</id>
    <published>2009-02-22T02:44:00Z</published>
    <updated>2009-02-22T22:01:24Z</updated>
    <category term="apache" />
    <category term="downloads" />
    <category term="files" />
    <link href="http://www.therailsway.com/2009/2/22/file-downloads-done-right" rel="alternate" type="text/html" />
    <title>File Downloads Done Right</title>
<content type="html">
            &lt;p&gt;Getting your file downloads right is one of the most important parts of your File Management functionality.  A poorly implemented download function can make your application painful to use, not just for downloaders, but for everyone else too.&lt;/p&gt;


	&lt;p&gt;Thankfully it’s also one of the easiest things to get right.&lt;/p&gt;


	&lt;h2&gt;The simple version&lt;/h2&gt;


	&lt;p&gt;For the purposes of this article let’s assume that your application needs to provide access to a large zip file, but that access should be restricted to logged in users.&lt;/p&gt;


	&lt;p&gt;The first choice we have to make is where to store this file.  In this case there’s really only one wrong answer, and that’s to store it in the public folder of your rails application. Every file stored in public will be served by our webserver without the involvement of our rails application.  This makes it impossible for us to check that the user has logged in.  Unless your files are &lt;strong&gt;completely&lt;/strong&gt; public, you shouldn’t go anywhere near the public folder.&lt;/p&gt;


	&lt;p&gt;So let’s assume we’ve stored the zip file in:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;/home/railsway/downloads/huge.zip&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Next we need a simple download action to send the file to the user, thankfully rails has this built right in:&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;
  before_filter :login_required
  def download
    send_file '/home/railsway/downloads/huge.zip', :type=&amp;gt;"application/zip" 
  end
&lt;/pre&gt;

	&lt;p&gt;Now when our users click the download link, they’ll be asked to choose a location and then be able to view the file.  The bad news is, there’s a catch here.   The good news is it’s easy to fix.&lt;/p&gt;


	&lt;h2&gt;What’s the catch?&lt;/h2&gt;


	&lt;p&gt;The problem here is one of scarce resources, and that resource is your rails processes.  Whether you’re using mongrel, fastcgi or passenger you have a limited number of rails processes available to handle application requests.  When one of your users makes a request, you want to know that you either have a process free to handle the request, or that one will become free in short order. If you don’t, users will face an agonizing wait for pages to load, or see their browser sessions timeout entirely.&lt;/p&gt;


	&lt;p&gt;When you use the default behaviour of send_file to send the file out to the user,  your rails process will read through the entire file, copying the contents of the file to the output stream as it goes.  For small files like images this probably isn’t that big of a deal, but for something enormous like a 200M zip file, using send_file will tie up a process for a long time. Users on slow connections will soak up a rails process for correspondingly longer.&lt;/p&gt;


	&lt;p&gt;If you get a large number of downloads running, you may find all your rails processes taken up by downloaders, with none left to serve any other users.  For all intents and purposes your site is down: you’ve instituted a denial of service attack against yourself.&lt;/p&gt;


	&lt;h2&gt;What about threads?&lt;/h2&gt;


	&lt;p&gt;Unfortunately threads in ruby won’t save us.  The combination of blocking IO and green threads mean that even though you’re doing the work in a thread, it’s blocking the entire process most of the time anyway.  JRuby users may get a performance improvement, but it’s still going to be a noticeable consumption of resources when compared to letting a web server stream the file.&lt;/p&gt;


	&lt;p&gt;Don’t believe everything you read on the internet, threads and ruby just won’t help you with most of this stuff.&lt;/p&gt;


	&lt;h2&gt;So What’s the Solution?&lt;/h2&gt;


	&lt;p&gt;Thankfully this problem was solved a long time ago by the guys at live journal. They used perl instead of ruby, but had the same problems.  Downloading files would block their application processes for too long, and cause other users to have to wait.  Their solution was elegant and simple.  Instead of making the application processes stream the file to the user, they simply tell the webserver what file to send, and let the web server bother with the details of streaming the file out to the client.&lt;/p&gt;


	&lt;p&gt;Their particular solution is quite cumbersome to set up and use, but there’s a very similar solution available called X-Sendfile.  It’s supported out of the box with later versions of lighttpd, and available as a &lt;a href="http://tn123.ath.cx/mod_xsendfile/"&gt;module for apache&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The way it works is instead of sending the file to our users, our rails application will simply check they’re allowed to download it (using our login_required filter) then write the name of the file into a special response header then render an empty response.  Once apache sees that response it will read the file from disk and stream it out to the user.  So your headers will look something like:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;X-Sendfile: /home/railsway/downloads/huge.zip&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;The apache module has a slightly annoying default setting that prevents it from sending files outside the public folder, so you’ll need to add the following configuration option:&lt;/p&gt;


	&lt;pre&gt;&lt;code&gt;XSendFileAllowAbove on&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;Thankfully for rails users x-sendfile support is built right in to rails, allowing us to make a few minor changes and we’re done.&lt;/p&gt;


&lt;pre class="sh_ruby"&gt;  
  before_filter :login_required
  def download
    send_file '/home/railsway/downloads/huge.zip', :type=&amp;gt;"application/zip", :x_sendfile=&amp;gt;true
  end
&lt;/pre&gt;

	&lt;p&gt;With that, we’re done.  Our rails process just make a quick authorization check and render a short response, and apache uses its own optimised file streaming code to send the file down to our users. Meanwhile, the rails process is free to go on to the next request.&lt;/p&gt;


	&lt;p&gt;Nginx users can use a similar header called X-AccelRedirect.  This is a little more fiddly to set up, and requires your application to write a special internal &lt;span class="caps"&gt;URL&lt;/span&gt; to the http response rather than the full path, but in terms of scalability and resource contention, it’s just as great.  There’s an &lt;a href="http://blog.kovyrin.net/2006/11/01/nginx-x-accel-redirect-php-rails/"&gt;intro to the nginx module&lt;/a&gt; available if you’re an nginx user.  If only uploads were this easy!&lt;/p&gt;


	&lt;h2&gt;Up Next&lt;/h2&gt;


	&lt;p&gt;The next article in the series will cover my experiences when dealing with the &lt;strong&gt;storage&lt;/strong&gt; of your files.  Should you use S3?  What about blobs, &lt;span class="caps"&gt;NFS&lt;/span&gt;, GFS or MogileFS?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-02-12:11274</id>
    <published>2009-02-12T05:34:00Z</published>
    <updated>2009-02-21T06:01:10Z</updated>
    <category term="downloads" />
    <category term="files" />
    <category term="uploads" />
    <link href="http://www.therailsway.com/2009/2/12/file-management" rel="alternate" type="text/html" />
    <title>File Management</title>
<content type="html">
            &lt;p&gt;One of the most common features for web applications I’ve built over the last 4 years doing rails is file management.  Users download file attachments in almost every web application I use.  Thankfully rails has a really capable suite of file management tools, and there are several great plugins to handle some of the more mundane functionality you’d need.&lt;/p&gt;


	&lt;p&gt;Over the next month or so I’m going to cover the set of techniques I use when building file management solutions for my clients, and some really exciting up and coming solutions which solve the last of my annoyances.&lt;/p&gt;


	&lt;p&gt;The rough order of business will be:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;File Downloads Done Right&lt;/li&gt;
		&lt;li&gt;File Management Plugins&lt;/li&gt;
		&lt;li&gt;Painless File Uploads&lt;/li&gt;
		&lt;li&gt;Storing your Files&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;If there’s anything in particular that you’d like to see covered, let me know in the comments.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-01-06:10174</id>
    <published>2009-01-06T07:12:00Z</published>
    <updated>2009-01-06T07:20:06Z</updated>
    <category term="performance" />
    <category term="scalability" />
    <category term="speed" />
    <link href="http://www.therailsway.com/2009/1/6/requests-per-second" rel="alternate" type="text/html" />
    <title>Requests Per Second</title>
<content type="html">
            &lt;p&gt;One of the most harmful things about people discussing the performance of web applications is the key metric that we use.  Requests per second seems like the obvious metric to use, but it has several insidious characteristics that poison the discourse and lead developers down ever deeper rabbit holes chasing irrelevant gains.  The metric prevents us from doing A/B comparisons, or discussing potential improvements without doing some mental arithmetic which appears beyond the capabilities of most of us.&lt;/p&gt;


	&lt;p&gt;Instead of talking about requests per second, we should always be focussed on the duration of a given request.  It’s what our users notice, and it’s the only thing which gives us a notice.&lt;/p&gt;


	&lt;p&gt;I should prefix the remaining discussion here by saying that most of it does &lt;strong&gt;not&lt;/strong&gt; apply to discussing performance problems at the scale of facebook, google or yahoo.  The thing is, statistically speaking, none of you are building applications that will operate at that scale.  Sorry if I’m the one who broke this to you, but you’re not building the next google :).&lt;/p&gt;


	&lt;p&gt;I should also state that requests per second is a really interesting metric when considering the throughput of a whole cluster.  But throughput isn’t performance.&lt;/p&gt;


	&lt;h2&gt;Diminshing marginal returns&lt;/h2&gt;


	&lt;p&gt;The biggest problem I have with requests per second is the fact that developers seem incapable of knowing when to stop optimising their applications.  As the requests per second get higher and higher, the improvements become less and less relevant.  This lets us think we’ve defeated &lt;a href="http://en.wikipedia.org/wiki/Vilfredo_Pareto"&gt;that pareto guy&lt;/a&gt;, while we waste ever-larger amounts of our employers’ time.&lt;/p&gt;


	&lt;p&gt;Let’s take two different performance improvements and compare them using both duration and req/s.&lt;/p&gt;


&lt;table&gt;
    &lt;tr&gt;
        Patch
        Before
        After
        Improvement
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;A&lt;/td&gt;
        &lt;td&gt;120 req/s&lt;/td&gt;
        &lt;td&gt;300 req/s&lt;/td&gt;
        &lt;td&gt;&lt;strong&gt;180 req/s&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;B&lt;/td&gt;
        &lt;td&gt;3000 req/s&lt;/td&gt;
        &lt;td&gt;4000 req/s&lt;/td&gt;
        &lt;td&gt;&lt;strong&gt;1000 req/s&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

	&lt;p&gt;As you can see, when you use req/s as your metric, change B seems like a &lt;span class="caps"&gt;MUCH&lt;/span&gt; bigger saving.  It improves performance by 1000 requests a second instead of that measly 180, give that guy a raise!  But let’s see what happens when we switch to using durations:&lt;/p&gt;


&lt;table&gt;
    &lt;tr&gt;
        Patch
        Before
        After
        Improvement
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;A&lt;/td&gt;
        &lt;td&gt;8.33 ms&lt;/td&gt;
        &lt;td&gt;3.33 ms&lt;/td&gt;
        &lt;td&gt;&lt;strong&gt;5 ms&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;B&lt;/td&gt;
        &lt;td&gt;0.33 ms&lt;/td&gt;
        &lt;td&gt;0.25 ms&lt;/td&gt;
        &lt;td&gt;&lt;strong&gt;0.08 ms&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

	&lt;p&gt;You see that the actual changes in duration in B is vanishingly tiny.  8% of one millisecond!  Odds are that that improvement will vanish into statistical noise when compared to the latency of your network, or your user’s internet connection.&lt;/p&gt;


	&lt;p&gt;But when we use requests per second, that 1000 is so big and enticing that developers will do almost anything to get it.  If they used durations as their metric, they’d probably have spent that time implementing a neat new feature, or responding to customer feedback.&lt;/p&gt;


	&lt;h2&gt;Deltas become meaningless&lt;/h2&gt;


	&lt;p&gt;A special case of my first complaint is that with requests per second the deltas aren’t meaningful without knowing the start and the finish points.  As I showed above, a 1000 req/s change could be a tiny change, but it could also be an amazing performance coup.  Take this next example:&lt;/p&gt;


&lt;table&gt;
    &lt;tr&gt;
        Before
        After
        Diff
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;1 req/s&lt;/td&gt;
        &lt;td&gt;1001 req/s&lt;/td&gt;
        &lt;td&gt;1000 req/s&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

	&lt;p&gt;When expressed as durations you can see that it made a huge difference&lt;/p&gt;


&lt;table&gt;
    &lt;tr&gt;
        Before
        After
        Diff
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;1000 ms&lt;/td&gt;
        &lt;td&gt;0.99 ms&lt;/td&gt;
        &lt;td&gt;999.01 ms&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

	&lt;p&gt;So 1000 requests per second could either be irrelevant, or fantastic.  Durations don’t have this problem at all. 0.02ms is obviously questionable, and 999.01 ms is an obvious improvement.&lt;/p&gt;


	&lt;p&gt;This problem most commonly expresses itself when people say “that changeset took 50 requests per second off my application”.  Without the before and after numbers, we can’t tell if that’s a big deal, or if the guy needs to take a deep breath and get back to work.&lt;/p&gt;


	&lt;h2&gt;The numbers don’t add up&lt;/h2&gt;


	&lt;p&gt;Finally, requests per second don’t lend themselves nicely to arithmetic, and make developers make silly decisions.  The most common case I see this is when comparing web servers to put in front of their rails applications.  The reasoning goes something like this:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Nginx does over 9000 requests per second, and apache only does 6000 requests per second!! I’d better use nginx unless I want to pay a 3000 requests per second tax.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;When people do this comparison they seem to believe that by switching to nginx from apache their application will go from 100 req/s to 3100 req/s.  As always, durations tell us a different story.&lt;/p&gt;


&lt;table&gt;
    &lt;tr&gt;
        Apache
        Nginx
        Diff
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;6000 req/s&lt;/td&gt;
        &lt;td&gt;9000 req/s&lt;/td&gt;
        &lt;td&gt;3000 req/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;0.16 ms&lt;/td&gt;
        &lt;td&gt;0.11 ms&lt;/td&gt;
        &lt;td&gt;0.05 ms&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

	&lt;p&gt;So we can see that odds are you’ll only gain a 5% of a millisecond’s improvement when switching.  Perhaps that improvement is worthwhile for your application, but is it worth the additional complexity?&lt;/p&gt;


	&lt;h2&gt;Conclusion&lt;/h2&gt;


	&lt;p&gt;Durations are a much more useful, and more honest, metric when comparing performance changes in your applications.  Requests per second is too wide-spread for us to stop using it entirely, but &lt;strong&gt;please&lt;/strong&gt; don’t use it when talking about performance of your web applications or libraries.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2009-01-02:10097</id>
    <published>2009-01-02T03:52:00Z</published>
    <updated>2009-01-02T03:55:10Z</updated>
    <link href="http://www.therailsway.com/2009/1/2/the_rails_way-awaken" rel="alternate" type="text/html" />
    <title>@the_rails_way.awaken!</title>
<content type="html">
            &lt;p&gt;After more than 15 months since the last post, and constant questions from users, I’m finally ready to bring The Rails Way back from hibernation.&lt;/p&gt;


	&lt;p&gt;The challenge I had here was the amount of time involved.  Review articles are incredibly time consuming, scouring an application for code to improve can take hours, making the changes takes time, and all of that is dependent on getting that perfect submission.&lt;/p&gt;


	&lt;p&gt;So while I intend to continue to do review pieces here (keep those submissions coming in) I’m going to extend the format here to include a few different kinds of posts.  I’ll be doing some focussed introductory pieces which cover the best practices for a few tricky areas that I see experienced rails programmers getting wrong.  I’ll also be doing a few ‘soapboxy’ pieces where I can address misinformation about Rails and Ruby or just advocate a particular piece of technology or code that I think is really cool.&lt;/p&gt;


	&lt;p&gt;One of my primary goals with this relaunch will be to post regularly, but I’m not going to try and stick to a schedule that takes the fun out of it for me.  Some weeks might see multiple posts, and others will see none at all.  I’m just hoping that you guys will enjoy most of them.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2007-10-04:7801</id>
    <published>2007-10-04T08:12:00Z</published>
    <updated>2009-01-02T03:29:50Z</updated>
    <link href="http://www.therailsway.com/2007/10/4/many-skinny-methods" rel="alternate" type="text/html" />
    <title>Many Skinny Methods</title>
<content type="html">
            &lt;p&gt;This refactoring is based on a topic &lt;a href="http://www.marcelmolina.com/"&gt;Marcel&lt;/a&gt; and I covered at RailsConf Europe.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Expense&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  belongs_to &lt;span class="sy"&gt;:payee&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  protected&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# Nice and concise, but what happens as we add more rules&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# and how do we write test cases for the four different possible &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# validation states?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;validate&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      errors.add(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Not enough funds&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;if&lt;/span&gt; payee.balance - amount &amp;gt; &lt;span class="i"&gt;0&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      errors.add(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Charge is too great&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;if&lt;/span&gt; payee.account.maximum_allowable_charge &amp;gt; amount&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Expense&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  belongs_to  &lt;span class="sy"&gt;:payee&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Instead of one large validation method, break each individual&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# rule into methods, and declare them here.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validate      &lt;span class="sy"&gt;:ensure_balance_is_sufficient_to_cover_amount&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validate      &lt;span class="sy"&gt;:amount_does_not_exceed_maximum_allowable_charge&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  protected&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# These validation callbacks simply add error messages if a particular &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# condition is met.   Each of them can be tested and understood on their own&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# without having to understand the entire body of the validate method.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;ensure_balance_is_sufficient_to_cover_amount&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      errors.add(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Not enough funds&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;if&lt;/span&gt; insufficient_funds?&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;amount_does_not_exceed_maximum_allowable_charge&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      errors.add(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Charge is too great&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;if&lt;/span&gt; exceeds_maximum_allowable_charge?&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# By defining separate predicate methods we can test each of them individually&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# and new programmers can see the intent of the code, not just the implementation.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# Instead of subtracting the amount from the balance and checking if the&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# value is greater than 0,  change the implementation to mirror the intent.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# There was a bug in the before code,  this is more obvious.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;insufficient_funds?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      amount &amp;gt; payee.balance&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;exceeds_maximum_allowable_charge?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      payee.account.maximum_allowable_charge &amp;gt; amount&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;While the refactored version may have more lines of code, but don’t let that scare you.  It’s far more important for code to be human readable than incredibly concise.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2007-09-03:7800</id>
    <published>2007-09-03T04:26:00Z</published>
    <updated>2009-01-02T01:43:55Z</updated>
    <link href="http://www.therailsway.com/2007/9/3/using-activeresource-to-consume-web-services" rel="alternate" type="text/html" />
    <title>Using ActiveResource to consume web-services</title>
<content type="html">
            &lt;p&gt;Today I’m reviewing Joe Van Dyk’s &lt;a href="http://code.google.com/p/monkeycharger/"&gt;monkeycharger&lt;/a&gt; application, which is a web-service for storing and charging credit cards. I loved looking at this app, because its only interface is a RESTful web service: there is no &lt;span class="caps"&gt;HTML&lt;/span&gt; involved. (If you’ve never written an app that only exposes a web-service UI, you ought to. It’s a blast.)&lt;/p&gt;


	&lt;p&gt;In general, Joe has done a fantastic job with keeping the controllers slim and moving logic to models. The only significant gripe I had with the application is that it is not ActiveResource compatible.&lt;/p&gt;


	&lt;p&gt;For those of you that are late to the party, ActiveResource is the newest addition to the Rails family. It lets you declare and consume web-services using an ActiveRecord-like interface…BUT. It is opinionated software, just like the rest of Rails, and makes certain assumptions about the web-services being consumed.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;The service must understand Rails-style &lt;span class="caps"&gt;REST&lt;/span&gt; URLs. (e.g. “POST /credit_cards.xml” to create a credit card, etc.)&lt;/li&gt;
		&lt;li&gt;The service must respond with a single &lt;span class="caps"&gt;XML&lt;/span&gt;-serialized object (Rails-style).&lt;/li&gt;
		&lt;li&gt;The service must make appropriate use of &lt;span class="caps"&gt;HTTP&lt;/span&gt; status codes (404 if the requested record cannot be found, 422 if any validations fail, etc.).&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;It’s really not much to ask, and working with ActiveResource (or “ares” as we affectively call it) is a real joy.&lt;/p&gt;


	&lt;p&gt;However, monkeycharger tends to do things like the following:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;AuthorizationsController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;create&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@credit_card&lt;/span&gt;   = &lt;span class="co"&gt;Authorizer&lt;/span&gt;.prepare_credit_card_for_authorization(params)&lt;tt&gt;
&lt;/tt&gt;    transaction_id = &lt;span class="co"&gt;Authorizer&lt;/span&gt;::authorize!(&lt;span class="sy"&gt;:amount&lt;/span&gt; =&amp;gt; params[&lt;span class="sy"&gt;:amount&lt;/span&gt;], &lt;span class="sy"&gt;:credit_card&lt;/span&gt; =&amp;gt; &lt;span class="iv"&gt;@credit_card&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    response.headers[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;X-AuthorizationSuccess&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;] = &lt;span class="pc"&gt;true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    render &lt;span class="sy"&gt;:text&lt;/span&gt; =&amp;gt; transaction_id&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;rescue&lt;/span&gt; &lt;span class="co"&gt;AuthorizationError&lt;/span&gt; =&amp;gt; e&lt;tt&gt;
&lt;/tt&gt;    render &lt;span class="sy"&gt;:text&lt;/span&gt; =&amp;gt; e.message&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Three things: the request is not representing an “authorization” object, the response is not &lt;span class="caps"&gt;XML&lt;/span&gt;, and errors are not employing &lt;span class="caps"&gt;HTTP&lt;/span&gt; status codes to indicate failure.&lt;/p&gt;


	&lt;p&gt;Fortunately, this is all really, really easy to fix. First, you need (for this specific example) an Authorization model (to encapsulate both the the &lt;span class="caps"&gt;XML&lt;/span&gt; serialization and the actual authorization).&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Authorization&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  attr_reader &lt;span class="sy"&gt;:attributes&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;initialize&lt;/span&gt;(attributes)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@attributes&lt;/span&gt; = attributes&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;credit_card&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@credit_card&lt;/span&gt; ||= &lt;span class="co"&gt;Authorizer&lt;/span&gt;.prepare_credit_card_for_authorization(attributes)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;authorize!&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@transaction_id&lt;/span&gt; = &lt;span class="co"&gt;Authorizer&lt;/span&gt;.authorize!(&lt;span class="sy"&gt;:amount&lt;/span&gt; =&amp;gt; attributes[&lt;span class="sy"&gt;:amount&lt;/span&gt;],&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="sy"&gt;:credit_card&lt;/span&gt; =&amp;gt; credit_card)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;to_xml&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    { &lt;span class="sy"&gt;:transaction_id&lt;/span&gt; =&amp;gt; &lt;span class="iv"&gt;@transaction_id&lt;/span&gt; }.to_xml(&lt;span class="sy"&gt;:root&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;authorization&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Then, we rework the AuthorizationsController to use the model:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;AuthorizationsController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;create&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    authorization = &lt;span class="co"&gt;Authorization&lt;/span&gt;.new(params[&lt;span class="sy"&gt;:authorization&lt;/span&gt;])&lt;tt&gt;
&lt;/tt&gt;    authorization.authorize!&lt;tt&gt;
&lt;/tt&gt;    render &lt;span class="sy"&gt;:xml&lt;/span&gt; =&amp;gt; authorization.to_xml, &lt;span class="sy"&gt;:status&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:created&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;rescue&lt;/span&gt; &lt;span class="co"&gt;AuthorizationError&lt;/span&gt; =&amp;gt; e&lt;tt&gt;
&lt;/tt&gt;    render &lt;span class="sy"&gt;:xml&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;&amp;lt;errors&amp;gt;&amp;lt;error&amp;gt;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;e.message&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;&amp;lt;/error&amp;gt;&amp;lt;/errors&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:status&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:unprocessable_entity&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;(Note the use of the “created” status, which is &lt;span class="caps"&gt;HTTP&lt;/span&gt; status code 201. Other verbs just use “ok”, status code 200, to indicate success. Also, with an error, we return an “unprocessable_entity” status, which is &lt;span class="caps"&gt;HTTP&lt;/span&gt; status code 422. ActiveResource will treat that as a failed validation.)&lt;/p&gt;


	&lt;p&gt;With that change, you could now use ActiveResource to authorize a credit card transaction:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Authorization&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveResource&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="pc"&gt;self&lt;/span&gt;.site = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://my.monkeycharger.site&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;auth = &lt;span class="co"&gt;Authorization&lt;/span&gt;.new(&lt;span class="sy"&gt;:amount&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;15&lt;/span&gt;, &lt;span class="sy"&gt;:credit_card_id&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;1234&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:remote_key&lt;/span&gt; =&amp;gt; remote_key_for_card)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;if&lt;/span&gt; auth.save&lt;tt&gt;
&lt;/tt&gt;  puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;success: &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;auth.transaction_id&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;error: &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;auth.errors.full_messages.to_sentence&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;It should be mentioned, too, that making an app ActiveResource-compatible does nothing to harm compatibility with non-ActiveResource clients. Everything is &lt;span class="caps"&gt;XML&lt;/span&gt;, both ways, with &lt;span class="caps"&gt;HTTP&lt;/span&gt; status codes being used to report whether a request succeeded or not. Win-win!&lt;/p&gt;


	&lt;p&gt;Obviously, real, working code trumps theoretical whiteboard sketches every time, and Joe is to be congratulated on what’s done. Even though ActiveResource-compatibility can buy you a lot, you should always evaluate whether you really need it and implement accordingly.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2007-08-20:7799</id>
    <published>2007-08-20T02:24:00Z</published>
    <updated>2009-01-02T01:43:54Z</updated>
    <link href="http://www.therailsway.com/2007/8/20/testing-the-right-stuff" rel="alternate" type="text/html" />
    <title>Testing the Right Stuff</title>
<content type="html">
            &lt;p&gt;I’m going to take a slightly different tack here, and review some of the unit tests in rails itself.  They show up two common anti patterns, spurious assertions  and coupling your tests to the implementation.&lt;/p&gt;


	&lt;p&gt;Perhaps the biggest benefit of a suite of unit tests is that they can provide a safety net, preventing you from accidentally adding new bugs or introducing regressions of old bugs.  With a large codebase, the unit tests can also help new developers understand your intent, though they’re &lt;a href="http://fishbowl.pastiche.org/2006/10/08/comment_your_performance_hacks"&gt;no substitute for comments&lt;/a&gt;.  However if you’re not careful with what gets included in your test cases, you can end up with a liability.&lt;/p&gt;


	&lt;h2&gt; Be careful what you assert&lt;/h2&gt;


	&lt;p&gt;Whenever you add an assertion to your test suite you’re sending a signal to future developers that the behaviour you’re asserting is both &lt;strong&gt;intentional&lt;/strong&gt; and &lt;strong&gt;desired&lt;/strong&gt;.  Future developers who try to refactor your code will see a failing test, and either give up, or waste time trying to figure out if the assertion is ‘real’ or whether it was merely added because that’s what the code happened to do at present.&lt;/p&gt;


	&lt;p&gt;For an example, take the &lt;a href="http://dev.rubyonrails.org/browser/trunk/activerecord/test/associations_test.rb?rev=7314#L1464"&gt;test_hatbm_attribute_access_and_respond_to from associations_test.rb&lt;/a&gt; , especially  the assertions that the project responds to access_level= and joined_on=.  Because of the current implementation of respond_do?, those assertions pass.  But should they?&lt;/p&gt;


	&lt;p&gt;In reality while those values will get stored in the object, they’ll never be written back to the database.  This is a surprising result for some developers, and removing those accessor methods would go a long way to helping avoid some frustrating moments.&lt;/p&gt;


	&lt;h2&gt; Mock and Stub with care&lt;/h2&gt;


	&lt;p&gt;Mock object frameworks like flexmock and mocha make it really easy to test how your code interacts with another system or a third party library.  However you should make sure that the thing that you’re mocking doesn’t merely reflect the &lt;strong&gt;current&lt;/strong&gt; implementation of a method.   To take a case from rails,  take a look at &lt;a href="http://dev.rubyonrails.org/browser/trunk/actionpack/test/controller/routing_test.rb?rev=7314#L198"&gt;setup_for_named_route in routing_test.rb&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;It takes the seemingly sensible approach of building a stubbed-out implementation of url_for instead of trying to build a full implementation into the test cases.  The stubbed version of url_for simply returns the arguments it was passed, this makes it extremely easy to work with and to test.&lt;/p&gt;


	&lt;p&gt;The problem is not with stubbing out the method, but in the way it is used in all the named route test cases.  Take &lt;a href="http://dev.rubyonrails.org/browser/trunk/actionpack/test/controller/routing_test.rb?rev=7314#L191"&gt;test_named_route_with_nested_controller&lt;/a&gt;.&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;test_named_route_with_nested_controller&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  rs.add_named_route &lt;span class="sy"&gt;:users&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;admin/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/admin/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  x = setup_for_named_route.new&lt;tt&gt;
&lt;/tt&gt;  assert_equal({&lt;span class="sy"&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/admin/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:use_route&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:users&lt;/span&gt;, &lt;span class="sy"&gt;:only_path&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;false&lt;/span&gt;},&lt;tt&gt;
&lt;/tt&gt;  x.send(&lt;span class="sy"&gt;:users_url&lt;/span&gt;))&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The strange hash value you see in the assertion is the result of the named route method calling url_for, and returning that.  The &lt;a href="http://dev.rubyonrails.org/browser/trunk/actionpack/lib/action_controller/routing.rb?rev=7314#L1169"&gt;current implementation of the named route helpers&lt;/a&gt; does this, but what if you wanted to &lt;a href="http://git.koziarski.com/?p=.git;a=shortlog;h=fast_path_method"&gt;implement a new version of named routes which completely avoids the costly call to url_for&lt;/a&gt;?  Every single named route test fails, even though applications which use those methods will work fine.&lt;/p&gt;


	&lt;p&gt;In this situation you have two options, you could make your tests depend on the full implementation of url_for.  This would probably slow down your test cases, and require a lot more setup code, but because the return values are correct you’re not likely to impede future refactoring.&lt;/p&gt;


	&lt;p&gt;The other option is to use different stubs for every test case.  Leaving you with something like this:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;test_named_route_with_nested_controller&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  rs.add_named_route &lt;span class="sy"&gt;:users&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;admin/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/admin/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:action&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  generated_url = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://test.named.routes/admin/user&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  x = setup_for_named_route.new&lt;tt&gt;
&lt;/tt&gt;  x.stubs(&lt;span class="sy"&gt;:url_for&lt;/span&gt;).returns(generated_url)&lt;tt&gt;
&lt;/tt&gt;  assert_equal(generated_url,  x.send(&lt;span class="sy"&gt;:users_url&lt;/span&gt;))&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Doing this for each and every test case is going to be quite time consuming and make your test cases extremely verbose.  As with all things in software you’ll have to make a judgement call on this trade off and make a choice between coupling or verbosity.&lt;/p&gt;


	&lt;p&gt;Whatever approach you choose, just remember that misleading test ‘failures’ can slow down refactoring, and end up &lt;strong&gt;reducing&lt;/strong&gt; your ability to respond to change.  As satisfying as ‘100% coverage’ or 2:1 ratios may be, don’t blindly add assertions or mock objects just to satisfy a tool.   Every line in your test cases should be there for a reason, and should be placed there with just as much care as you’d use for a line of application code.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2007-08-01:7798</id>
    <published>2007-08-01T16:10:00Z</published>
    <updated>2009-01-02T01:43:54Z</updated>
    <link href="http://www.therailsway.com/2007/8/1/dangers-of-cargo-culting" rel="alternate" type="text/html" />
    <title>Dangers of Cargo-culting</title>
<content type="html">
            &lt;p&gt;“Cargo culting”, when used in a computer-programming context, refers to the practice of using techniques (or even entire blocks of code) seen elsewhere without wholly understanding how they work. (The term “cargo cult”, if you are unfamiliar with it, has its own fascinating etymology, which is covered nicely at &lt;a href="http://en.wikipedia.org/wiki/Cargo_cult"&gt;wikipedia&lt;/a&gt;.) Cargo culting is a dangerous phenomenon, watering down the state of the art and encouraging cookie-cutter code shoved blindly into black boxes.&lt;/p&gt;


	&lt;p&gt;Consider the following snippet of code, taken from a project that was submitted to us some time ago. (Alas, I cannot find the original submitter—I apologize for that!)&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;account_code?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  !! &lt;span class="iv"&gt;@account_code&lt;/span&gt;.nil?&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;To me, this looks cargo-culted, since it is seems that the programmer did not understand what the ”!!” idiom was all about. They probably saw it used somewhere and “cargo culted” it, using it without knowledge, assuming that it was, for some reason, “necessary”.&lt;/p&gt;


	&lt;p&gt;Now, the way ”!!” works is this: take the value behind the ”!!”, negate it, and negate it again. It’s just double-negation: &lt;code&gt;!(!(@account_code.nil?))&lt;/code&gt;. The ultimate effect is to take some value, and convert it into an honest-to-goodness “true” or “false”. (In my ever-so-humble opinion, the ”!!” idiom is an abomination: it’s far too clever for its own good. First of all, you rarely ever need a real boolean value, and for those times you do, it is better to be explicit in the conversion, by using a ternary operator or full-blown &lt;code&gt;if&lt;/code&gt; statement, for instance.)&lt;/p&gt;


	&lt;p&gt;In other words, the double-negation of &lt;code&gt;nil?&lt;/code&gt; results in absolutely no difference from the use of &lt;code&gt;nil?&lt;/code&gt; by itself, since &lt;code&gt;nil?&lt;/code&gt; will return a true/false value. This, in turn, means the effect in the original is actually not what was intended for the &lt;code&gt;account_code?&lt;/code&gt; predicate. It should have returned “true” if the account code existed (was “non-nil”), not “false”. Thus, the method should have actually been written thus:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;account_code?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  ! &lt;span class="iv"&gt;@account_code&lt;/span&gt;.nil?&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;In this case, cargo-culting resulted in the code being buggy. This is not an uncommon outcome of using techniques or code without understanding their purpose. If you ever find yourself copying something into your own code, with a justfying “I-don’t-know-what-it-does, but-it-appears-to-work”, &lt;em&gt;stop immediately&lt;/em&gt;. Do some research. Figure it out. Learn what it means.&lt;/p&gt;


	&lt;p&gt;Further, note that unless you actually &lt;em&gt;need&lt;/em&gt; a true boolean value from that, you can shorten the implementation of the &lt;code&gt;account_code?&lt;/code&gt; predicate even further:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;account_code?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="iv"&gt;@account_code&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This works because Ruby treats &lt;code&gt;nil&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt; as false, and everything else as true.&lt;/p&gt;


	&lt;p&gt;If there is one thing that Koz and I want you, our readers, to come away from this site with, it is an understanding of &lt;em&gt;why&lt;/em&gt; you should do things one way and not another. Ultimately, it makes the difference between being a mediocre programmer, and becoming a great programmer.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2007-06-28:7797</id>
    <published>2007-06-28T02:39:00Z</published>
    <updated>2009-01-02T01:43:54Z</updated>
    <link href="http://www.therailsway.com/2007/6/28/free-for-all-tab-helper-summary" rel="alternate" type="text/html" />
    <title>Free-for-all: Tab Helper (Summary)</title>
<content type="html">
            &lt;p&gt;The &lt;a href="http://www.therailsway.com/2007/6/4/free-for-all-tab-helper"&gt;first RailsWay free-for-all&lt;/a&gt; came off quite well. Many of you posted your favorite solutions to the problem of tab-based navigation, as posed by Nate Morse.&lt;/p&gt;


	&lt;h2&gt;Jamis’ Take&lt;/h2&gt;


	&lt;p&gt;Of all the solutions posted, my personal favorite was the pragmatic and simple &lt;span class="caps"&gt;CSS&lt;/span&gt;-based solution given by Mr. eel (Nate Morse came to the same solution independently):&lt;/p&gt;


&lt;blockquote&gt;

	&lt;p&gt;I take a completely different approach. &lt;span class="caps"&gt;I ID&lt;/span&gt; the body of the page with the name of the current controller. Then I use a descendent &lt;span class="caps"&gt;CSS&lt;/span&gt; selector to highlight the current tab based on the body id and an id given to each link. I don�t bother with replacing the current tab link with a span. If the user wants to click that link again� then it�s the same as refreshing. Totally up to them.&lt;/p&gt;


	&lt;p&gt;With html like:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&amp;lt;body id=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;ul&amp;gt;&lt;tt&gt;
&lt;/tt&gt;    &amp;lt;li&amp;gt;&amp;lt;a href=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; id=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;usersNav&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&amp;gt;&lt;span class="co"&gt;Users&lt;/span&gt;&amp;lt;&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;a&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;li&amp;gt;&lt;tt&gt;
&lt;/tt&gt;    &amp;lt;li&amp;gt;&amp;lt;a href=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/comments&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; id=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;commentsNav&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&amp;gt;&lt;span class="co"&gt;Comments&lt;/span&gt;&amp;lt;&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;a&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;li&amp;gt;&lt;tt&gt;
&lt;/tt&gt;    &amp;lt;li&amp;gt;&amp;lt;a href=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/posts&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; id=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;postsNav&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&amp;gt;&lt;span class="co"&gt;Posts&lt;/span&gt;&amp;lt;&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;a&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;li&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;ul&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;I would use &lt;span class="caps"&gt;CSS&lt;/span&gt; like this&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;#users&lt;/span&gt; &lt;span class="co"&gt;#usersNav&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;#comments&lt;/span&gt; &lt;span class="co"&gt;#commentsNav&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;#posts&lt;/span&gt; &lt;span class="co"&gt;#postsNav&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ke"&gt;background&lt;/span&gt;:&lt;span class="vl"&gt;red&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ke"&gt;font-weight&lt;/span&gt;:&lt;span class="vl"&gt;bold&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;/blockquote&gt;

	&lt;p&gt;What a great approach. Although I would make the choice of the body ID explicit (rather than depending on the controller name), it is otherwise really nice. It shrugs off the whole issue of “should the current tab be a link” by saying it just doesn’t matter—every tab is always a link. Such pragmatism gets right to the heart of the Rails Way: implement just what matters, and nothing more.&lt;/p&gt;


	&lt;h2&gt;Koz’s Take&lt;/h2&gt;


	&lt;p&gt;A number of solutions relied on tightly coupling the controller and tabs.  While this may seem like a time-saver at first, I believe that it’s unlikely to remain useful as your application grows.  You’ll find yourself moving functionality into strange locations in order to make your tabs highlight correctly.&lt;/p&gt;


	&lt;p&gt;The problem is amplified with a restful application where your choice of controllers are dictated by the resources that you’re managing.   You may have a list of comments in several different sections of your application, but not want to highlight the ‘comment’ tab whenever you display them.&lt;/p&gt;


	&lt;p&gt;Personally, I prefer the really simple approach of a before filter and a navigation partial.&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;set_current_tab&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="iv"&gt;@current_tab&lt;/span&gt; = &lt;span class="sy"&gt;:people&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Thanks, everyone for your submissions!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.therailsway.com/">
    <author>
      <name>Koz</name>
    </author>
    <id>tag:www.therailsway.com,2007-06-07:7796</id>
    <published>2007-06-07T02:49:00Z</published>
    <updated>2009-01-02T01:43:54Z</updated>
    <link href="http://www.therailsway.com/2007/6/7/railsconf-recap-named-callbacks" rel="alternate" type="text/html" />
    <title>RailsConf Recap: Named Callbacks</title>
<content type="html">
            &lt;p&gt;Another topic we touched briefly on at RailsConf was the idea of &lt;em&gt;named callbacks&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Consider this snippet (also from Brian Cooke’s expense tracking application):&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Expense&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  protected&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;before_create&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.created_at == &lt;span class="co"&gt;Time&lt;/span&gt;.now.to_date.to_time&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pc"&gt;self&lt;/span&gt;.created_at = &lt;span class="co"&gt;Time&lt;/span&gt;.now&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;One thing to keep in mind here is that when a new Expense record is created, the created_at column is used to track when the expense originally occurred, not when the record was created. As a special case, if the timestamp is 00:00 of the current day, then it is assumed to actually be the current time.&lt;/p&gt;


	&lt;p&gt;Now, looking at that code, it’s definitely not immediately obvious what it is trying to do. In fact, it took me a few minutes of steady concentration (and cross-referencing other parts of the project) to understand it. The fact that it uses a generic “before_create” callback makes it hard to know the purpose of the method, and the use of “Time.now.to_date.to_time” (though effective) is pretty intention-obscuring.&lt;/p&gt;


	&lt;p&gt;Here’s a clearer, more self-documenting approach, using a named callback:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Expense&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  before_create &lt;span class="sy"&gt;:make_created_now_if_created_today&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  protected&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;make_created_now_if_created_today&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.created_at == &lt;span class="co"&gt;Time&lt;/span&gt;.now.beginning_of_day&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pc"&gt;self&lt;/span&gt;.created_at = &lt;span class="co"&gt;Time&lt;/span&gt;.now&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The named callback helps make it clearer what the purpose of the method is (though in this case, an additional comment would not be amiss). Also, ActiveSupport comes to the rescue, allowing us to convert the convoluted “Time.now.to_date.to_time” into the more self-documenting “Time.now.beginning_of_day”. (Alternatively, you might prefer “Time.now.midnight”, though I find “beginning_of_day” to be clearer, since it reveals the intention better.)&lt;/p&gt;


	&lt;p&gt;Always look for ways to make your code document itself. Ruby is one of the most readable programming languages I’ve ever used, and it’s a pity to not take advantage of that readability as often as you can.&lt;/p&gt;
          </content>  </entry>
</feed>
