<?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" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

 <title>Jerry Shen</title>
 
 <link href="http://www.hansay.com/" />
 <updated>2012-02-14T16:01:50+00:00</updated>
 <id>http://www.hansay.com/</id>
 <author>
   <name>Jerry Shen</name>
   <email>hansay99@gmail.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/JerryShen" /><feedburner:info uri="jerryshen" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>Using APN Sender to Send Push Notifications to Your IOS Devices</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/wEVHLUD794c/" />
   <updated>2012-02-14T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2012/02/14/using-apn-sender-to-send-push-notifications-to-your-ios-devices</id>
   <content type="html">&lt;p&gt;Happy Valentine's Day.&lt;/p&gt;

&lt;p&gt;Recently, I have a project based on both ruby on rails and iPhone applications, there is a requirement that is pushing notifications from server side to iPhone client, and I built a server component of an iPhone application in Ruby with &lt;a href="https://github.com/kdonovan/apn_sender"&gt;apn_sender&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I want to send background notifications through Apple Push Notification servers, which I was stumbled at first, to setup the plugin is very simple, but I couldn't receive any notifications after sending them, it's very weird that everything seemed right. After further testing and trying, I found the problem is format of IOS Device Token, Because I encoded and stored it in mongodb as a Base64 string, So I have to decode it to hexadecimal.&lt;/p&gt;

&lt;p&gt;APN Sender is based on Resque and Redis, so I wrote a script to skip the Resque Queue to make development easier.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;

    &lt;span class="n"&gt;ios_device_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Jerry&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ios_device_token&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ios_device_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unpack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;H*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\w{8}/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;notification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;APN&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Notification&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:alert&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hey, how are you?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:sound&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:badge&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;APN&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:verbose&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:environment&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;production&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_to_apple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The app installed on my iPhone is based on Ad Hoc, it's very important that you should set the environment to production when you initialize the sender object, otherwise you would receive nothing.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2012/02/14/using-apn-sender-to-send-push-notifications-to-your-ios-devices/</feedburner:origLink></entry>
 
 <entry>
   <title>Solution for System Time Error When Compiling Packages</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/rGRvF7MN2Q0/" />
   <updated>2012-01-02T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2012/01/02/solution-for-system-time-error-when-compiling-packages</id>
   <content type="html">&lt;p&gt;I was trying to recompile Nginx today, But I got a very wierd error that I couldn't pass it.&lt;/p&gt;

&lt;p&gt;This is the error information,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;configure: error: newly created file is older than distributed files!
Check your system clock
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It seems that the file I created is older than the distributed files, then I checked the system clock,
I found the timezone was wrong, so I reseted the timezone with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo dpkg-reconfigure tzdata
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Choose your current timezone, and it will update your system clock.&lt;/p&gt;

&lt;p&gt;Awesome, it works.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2012/01/02/solution-for-system-time-error-when-compiling-packages/</feedburner:origLink></entry>
 
 <entry>
   <title>Counter Cache Reset for Counters</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/sVKIcozUS88/" />
   <updated>2012-01-01T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2012/01/01/counter-cache-reset</id>
   <content type="html">&lt;p&gt;When you want to implement &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/CounterCache.html"&gt;counter cache&lt;/a&gt;, how to handle the counters for the old data?
Generally you will add a migration which runs a script to update all the counts, unfortunately you wil get an error,
because the column is readonly, you can't update this column in a normal way.&lt;/p&gt;

&lt;p&gt;Model&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
      &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:counter_cache&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:resources_count&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Incorrect way&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InitializeResourcesCountForCategories&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;up&lt;/span&gt;
        &lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:resources_count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You should be using &lt;code&gt;User.reset_counters&lt;/code&gt; to do this&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InitializeResourcesCountForCategories&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;up&lt;/span&gt;
        &lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reset_counters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



</content>
 <feedburner:origLink>http://www.huangzhimin.com/2012/01/01/counter-cache-reset/</feedburner:origLink></entry>
 
 <entry>
   <title>Method Missing Best Practice</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/aasWiEsp1dU/" />
   <updated>2011-12-21T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/12/21/method-missing-best-practice</id>
   <content type="html">&lt;p&gt;Method missing allows access to the object attributes, which are held in the @attributes hash, as though they were first-class methods.&lt;/p&gt;

&lt;p&gt;If you call a method that doesn’t exist, Ruby will call the method_missing method, and pass the name of the method and any arguments you supplied, which means you can dynamically handle the method.&lt;/p&gt;

&lt;p&gt;Here we go, for example, we have a messages table:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;messages&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:force&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;     &lt;span class="s2"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boolean&lt;/span&gt;  &lt;span class="s2"&gt;&amp;quot;is_read&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="ss"&gt;:default&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boolean&lt;/span&gt;  &lt;span class="s2"&gt;&amp;quot;is_archived&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;  &lt;span class="s2"&gt;&amp;quot;post_id&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;  &lt;span class="s2"&gt;&amp;quot;user_id&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;created_at&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;updated_at&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;As a general way, many people will define some following methods&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Message&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
      
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_read?&lt;/span&gt;
        &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="n"&gt;is_read&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_archived?&lt;/span&gt;
        &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="n"&gt;is_archived&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mark_as_read!&lt;/span&gt;
        &lt;span class="n"&gt;update_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:is_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mark_as_unread!&lt;/span&gt;
        &lt;span class="n"&gt;update_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:is_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mark_as_archived!&lt;/span&gt;
        &lt;span class="n"&gt;update_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:is_archived&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mark_as_unarchived!&lt;/span&gt;
        &lt;span class="n"&gt;update_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:is_archived&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Wow, this makes your code ugly, we can use &lt;code&gt;method missing&lt;/code&gt; instead of these all methods&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;
        &lt;span class="k"&gt;when&lt;/span&gt;&lt;span class="sr"&gt; /^is_(un)?(.*)\?/&lt;/span&gt;
          &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vg"&gt;$1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;!&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;!!&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;is_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;when&lt;/span&gt;&lt;span class="sr"&gt; /^mark_as_(un)?(.*)!/&lt;/span&gt;
          &lt;span class="n"&gt;update_attribute&lt;/span&gt; &lt;span class="ss"&gt;:&amp;quot;is_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vg"&gt;$2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;When you call &lt;code&gt;is_[string]&lt;/code&gt; method or &lt;code&gt;mark_as_[string]&lt;/code&gt; method, as you can see, there is definitely no &lt;code&gt;is_[string]&lt;/code&gt; or &lt;code&gt;mark_as_[string]&lt;/code&gt; method, yet Rails is smart enough to call the method with the correct parameters, What we have done is to run a regular expression against the name of the method, and if it matches the pattern &lt;code&gt;is_[string]&lt;/code&gt; or &lt;code&gt;mark_as_[string]&lt;/code&gt; then it calls the method with the [string] part as the first parameter and the first argument as the second parameter. Pretty powerful, don't you think?&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/12/21/method-missing-best-practice/</feedburner:origLink></entry>
 
 <entry>
   <title>Running Multiple Rails Versions by Standalone Gemsets with Passenger</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/3kRfC6D8VEI/" />
   <updated>2011-12-13T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/12/13/running-multiple-rails-versions-on-server-by-standalone-gemsets-with-passenger</id>
   <content type="html">&lt;p&gt;There was a case before that troubled me a lot, I have many projects to run on production server that each one has a different rails version, and each project should be run in a standalone gemset with RVM, I have implemented it before, and now, I will make a guide to show you guys hwo to run multiple rails versions with phusion passenger and RVM.&lt;/p&gt;

&lt;p&gt;Just give a example to you guys, I have project 'foo' run with rails 3.0.10 and project 'bar' run with rails 3.1.3 which is the latest version for rails 3, As of Phusion Passenger 3 you can run all components as Phusion Passenger.&lt;/p&gt;

&lt;p&gt;The setup that we currently recommend is to combine Phusion Passenger for Nginx, with Phusion Passenger Standalone. All applications that are to use a different gemset can be served separately through Phusion Passenger Standalone and hook into the main web server via a setup load paths configuration.&lt;/p&gt;

&lt;p&gt;To run project 'foo' under gemset 'foo', you need to do several simple configurations below:&lt;/p&gt;

&lt;p&gt;First you need to add a &lt;code&gt;.rvmrc&lt;/code&gt; file to your rails root directory, I think every one may use this, if you don'y use rvmrc, never mind, just create it by yourself with&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rvm --rvmrc --create 1.9.3@foo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then the &lt;code&gt;.rvmrc&lt;/code&gt; file will be created, yeah, that's cool for the new functionanlity by RVM.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;config/setup_load_paths.rb&lt;/code&gt; file in config directory, prefill with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;MY_RUBY_HOME&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;MY_RUBY_HOME&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rvm&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="n"&gt;rvm_path&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;MY_RUBY_HOME&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;rvm_lib_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rvm_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;lib&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vg"&gt;$LOAD_PATH&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unshift&lt;/span&gt; &lt;span class="n"&gt;rvm_lib_path&lt;/span&gt;
        &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rvm&amp;#39;&lt;/span&gt;
        &lt;span class="no"&gt;RVM&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gemset_use!&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;LoadError&lt;/span&gt;
        &lt;span class="c1"&gt;# RVM is unavailable at this point.&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;RVM ruby lib is currently unavailable.&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Pick the lines for your version of Bundler&lt;/span&gt;
    &lt;span class="c1"&gt;# If you&amp;#39;re not using Bundler at all, remove all of them&lt;/span&gt;

    &lt;span class="c1"&gt;# Require Bundler 1.0 &lt;/span&gt;
    &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BUNDLE_GEMFILE&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;../Gemfile&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;bundler/setup&amp;#39;&lt;/span&gt;

    &lt;span class="c1"&gt;# Require Bundler 0/9&lt;/span&gt;
    &lt;span class="c1"&gt;# if File.exist?(&amp;quot;.bundle/environment.rb&amp;quot;)&lt;/span&gt;
    &lt;span class="c1"&gt;#   require &amp;#39;.bundle/environment&amp;#39;&lt;/span&gt;
    &lt;span class="c1"&gt;# else&lt;/span&gt;
    &lt;span class="c1"&gt;#   require &amp;#39;rubygems&amp;#39;&lt;/span&gt;
    &lt;span class="c1"&gt;#   require &amp;#39;bundler&amp;#39;&lt;/span&gt;
    &lt;span class="c1"&gt;#   Bundler.setup&lt;/span&gt;
    &lt;span class="c1"&gt;# end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The same as project &lt;code&gt;bar&lt;/code&gt;, the only difference is set a difference gemset.&lt;/p&gt;

&lt;p&gt;After these two configuration steps, you can deploy your project to server now,
if there is no gemset named 'foo' or 'bar on your server, you will got a error by running &lt;code&gt;cap deploy:setup&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ERROR: Gemset 'foo' does not exist, rvm gemset create 'foo' first.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Follow the error message, you need to create a gemset named 'foo' on your server first.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rvm use 1.9.3
$ rvm gemset create foo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then the foo gemset will be created, you can deploy your project to your server now,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cap deploy:setup
$ cap deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;'bundle install' will automatically install all the gems under 'foo' gemset and run server with the right rails version.&lt;/p&gt;

&lt;p&gt;Here is the deploy script:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="vg"&gt;$:&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unshift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./lib&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rvm_path&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;rvm/capistrano&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;ssh_options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:forward_agent&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:application&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:rvm_ruby_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;1.9.3@&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:rvm_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/jerry/.rvm&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:rvm_bin_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/home/jerry/.rvm/bin&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:rvm_trust_rvmrcs_flag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:scm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:git&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:repository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;your_git_repo_url_here&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:branch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;master&amp;quot;&lt;/span&gt;

    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:deploy_to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;your_deploy_path_here/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;jerry&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:use_sudo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;your_server_domain_or_ip_here&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:primary&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:deploy_via&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:copy&lt;/span&gt;

    &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ss"&gt;:configure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:roles&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:web&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ln -s &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;shared_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/config/database.yml &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;current_release&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/config/database.yml&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;cd &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;current_release&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; bundle install --without development test&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ss"&gt;:trust_rvmrc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:roles&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:web&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;rvm rvmrc trust &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;current_release&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;deploy:update_code&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:trust_rvmrc&lt;/span&gt;
    &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;deploy:update_code&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:configure&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Wish you happy with your deployment.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/12/13/running-multiple-rails-versions-on-server-by-standalone-gemsets-with-passenger/</feedburner:origLink></entry>
 
 <entry>
   <title>Rails Style Guide</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/U2W50BsABsU/" />
   <updated>2011-12-12T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/12/12/rails-style-guide</id>
   <content type="html">&lt;h1&gt;Abstract&lt;/h1&gt;

&lt;p&gt;This guide is copy from bbatsov's work.&lt;/p&gt;

&lt;p&gt;The goal of this guide is to present a set of best practices and style
prescriptions for Ruby on Rails 3 development. It's a complementary
guide to the already existing community-driven
&lt;a href="https://github.com/bbatsov/ruby-style-guide"&gt;Ruby coding style guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While in the guide the section &lt;a href="#testing"&gt;Testing Rails applications&lt;/a&gt; is after
&lt;a href="#developing"&gt;Developing Rails applications&lt;/a&gt; I truly believe that
Behaviour-Driven Development (BDD) is the best way to develop
software. Keep that in mind.&lt;/p&gt;

&lt;p&gt;Rails is an opinionated framework and this is an opinionated guide. In
my mind I'm totally certain that
&lt;a href="https://www.relishapp.com/rspec"&gt;RSpec&lt;/a&gt; is superior to Test::Unit,
&lt;a href="http://sass-lang.com/"&gt;Sass&lt;/a&gt; is superior to CSS and
&lt;a href="http://haml-lang.com/"&gt;Haml&lt;/a&gt; (&lt;a href="http://slim-lang.com/"&gt;Slim&lt;/a&gt;) is
superior to Erb. So don't expect to find any Test::Unit, CSS or Erb
advice in here.&lt;/p&gt;

&lt;p&gt;Some of the advice here is applicable only to Rails 3.1.&lt;/p&gt;

&lt;p&gt;You can generate a PDF or an HTML copy of this guide using
&lt;a href="https://github.com/TechnoGate/transmuter"&gt;Transmuter&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Table of Contents&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#developing"&gt;Developing Rails Applications&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#configuration"&gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#routing"&gt;Routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#controllers"&gt;Controllers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#models"&gt;Models&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#activerecord"&gt;ActiveRecord&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#migrations"&gt;Migrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#views"&gt;Views&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#assets"&gt;Assets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mailers"&gt;Mailers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#bundler"&gt;Bundler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#priceless"&gt;Priceless Gems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#flawed"&gt;Flawed Gems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#processes"&gt;Managing processes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#testing"&gt;Testing Rails Applications&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#cucumber"&gt;Cucumber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#rspec"&gt;RSpec&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#rspec_views"&gt;Views&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#rspec_controllers"&gt;Contollers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#rspec_models"&gt;Models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#rspec_mailers"&gt;Mailers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#rspec_uploaders"&gt;Uploaders&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#reading"&gt;Further Reading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#contributing"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#spreadtheword"&gt;Spread the word&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="developing"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Developing Rails applications&lt;/h1&gt;

&lt;p&gt;&lt;a name="configuration"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Configuration&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Put custom initialization code in &lt;code&gt;config/initializers&lt;/code&gt;. The code in
initializers executes on application startup.&lt;/li&gt;
&lt;li&gt;The initialization code for each gem should be in a separate file
with the same name as the gem, for example &lt;code&gt;carrierwave.rb&lt;/code&gt;,
&lt;code&gt;rails_admin.rb&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;Adjust accordingly the settings for development, test and production
environment (in the corresponding files under &lt;code&gt;config/environments/&lt;/code&gt;)

&lt;ul&gt;
&lt;li&gt;Mark additional assets for precompilation (if any):&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;        &lt;span class="c1"&gt;# config/environments/production.rb&lt;/span&gt;
        &lt;span class="c1"&gt;# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;precompile&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sx"&gt;%w( rails_admin/rails_admin.css rails_admin/rails_admin.js )&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;While not strictly related to style, in order to use
&lt;a href="https://github.com/jnicklas/carrierwave"&gt;carrierwave&lt;/a&gt; for the files
upload and &lt;a href="https://github.com/geemus/fog"&gt;fog&lt;/a&gt; for file storage, some
configuration needs to be applied in the
&lt;code&gt;config/initializers/carrierwave.rb&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# config/initializers/carrierwave.rb&lt;/span&gt;

    &lt;span class="c1"&gt;# Store the files locally for test environment&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test?&lt;/span&gt;
      &lt;span class="no"&gt;CarrierWave&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:file&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_processing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Using Amazon S3 for Development and Production&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;development?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;production?&lt;/span&gt;
      &lt;span class="no"&gt;CarrierWave&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tmp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;uploads&amp;#39;&lt;/span&gt;

        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:fog&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fog_credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;AWS&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;your_access_key_id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;your_secret_access_key&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fog_directory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;your_bucket&amp;#39;&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Do not use &lt;code&gt;fog&lt;/code&gt; for the test environment, use &lt;code&gt;file&lt;/code&gt; storage instead.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;fog&lt;/code&gt; for the development environment. This will prevent
unexpected problems on production.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="routing"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Routing&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When you need to add more actions to a RESTful resource (do you
really need them at all?) use &lt;code&gt;member&lt;/code&gt; and &lt;code&gt;collection&lt;/code&gt; routes.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;subscriptions/:id/unsubscribe&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:subscriptions&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:subscriptions&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;unsubscribe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:on&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:member&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;photos/search&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:photos&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:photos&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;search&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:on&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:collection&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;If you need to define multiple &lt;code&gt;member/collection&lt;/code&gt; routes use the
alternative block syntax.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:subscriptions&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;unsubscribe&amp;#39;&lt;/span&gt;
        &lt;span class="c1"&gt;# more routes&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:photos&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;search&amp;#39;&lt;/span&gt;
        &lt;span class="c1"&gt;# more routes&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use nested routes to express better the relationship between
ActiveRecord models.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
      &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:comments&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Comments&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
      &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:post&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# routes.rb&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:comments&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use namespaced routes to group related actions.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="c1"&gt;# Directs /admin/products/* to Admin::ProductsController&lt;/span&gt;
      &lt;span class="c1"&gt;# (app/controllers/admin/products_controller.rb)&lt;/span&gt;
      &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:products&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Never use the legacy wild controller route. This route will make all
actions in every controller accessible via GET requests.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# very bad&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;:controller(/:action(/:id(.:format)))&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="controllers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Controllers&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep the controllers skinny - they should only retrieve data for the
view layer and shouldn't contain any business logic (all the
business logic should naturally reside in the model).&lt;/li&gt;
&lt;li&gt;Each controller action should (ideally) invoke only one method other
than an initial find or new.&lt;/li&gt;
&lt;li&gt;Share no more than two instance variables between a controller and a view.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="models"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Models&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduce non-ActiveRecord model classes freely.&lt;/li&gt;
&lt;li&gt;Name the models with meaningful (but short) names without abbreviations.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="activerecord"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;ActiveRecord&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoid altering ActiveRecord defaults (table names, primary key, etc)
unless you have a very good reason (like a database that's not under
your control).&lt;/li&gt;
&lt;li&gt;Group macro-style methods (&lt;code&gt;has_many&lt;/code&gt;, &lt;code&gt;validates&lt;/code&gt;, etc) in the
beginning of the class definition.&lt;/li&gt;
&lt;li&gt;Always use the new
&lt;a href="http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3/"&gt;"sexy" validations&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;When a custom validation is used more than once or the validation is some regular expression mapping,
create a custom validator file.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
      &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sr"&gt; /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailValidator&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EachValidator&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;is not a valid email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;


    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
      &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;All custom validators should be moved to a shared gem.&lt;/li&gt;
&lt;li&gt;Use named scopes freely.&lt;/li&gt;
&lt;li&gt;When a named scope, defined with a lambda and parameters, becomes too
complicated it is preferable to make a class method instead which serves
the same purpose of the named scope and returns and
&lt;code&gt;ActiveRecord::Relation&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;Beware of the behavior of the &lt;code&gt;update_attribute&lt;/code&gt; method. It doesn't
run the model validations (unlike &lt;code&gt;update_attributes&lt;/code&gt;) and could easily corrupt the model state.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="migrations"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Migrations&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep the &lt;code&gt;schema.rb&lt;/code&gt; under version control.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;rake db:schema:load&lt;/code&gt; instead of &lt;code&gt;rake db:migrate&lt;/code&gt; to initialize
an empty database.&lt;/li&gt;
&lt;li&gt;Avoid setting defaults in the tables themselves. Use the model layer
instead.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;amount&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:amount&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;While the use of `self[:attr_name]` is considered fairly idiomatic,
you might also consider using the slightly more verbose (and arguably more
readable) `read_attribute` instead:
&lt;/code&gt;&lt;/pre&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;amount&lt;/span&gt;
      &lt;span class="n"&gt;read_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;When writing constructive migrations (adding tables or columns), use
the new Rails 3.1 way of doing the migrations - use the &lt;code&gt;change&lt;/code&gt;
method instead of &lt;code&gt;up&lt;/code&gt; and &lt;code&gt;down&lt;/code&gt; methods.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="views"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Views&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Never call the model layer directly from a view.&lt;/li&gt;
&lt;li&gt;Never make complex formatting in the views, export the formatting to
a method in the view helper or the model.&lt;/li&gt;
&lt;li&gt;Mitigate code duplication by using partial templates and layouts.&lt;/li&gt;
&lt;li&gt;Add
&lt;a href="https://github.com/bcardarella/client_side_validations"&gt;client side validation&lt;/a&gt;
for the custom validators. The steps to do this are:

&lt;ul&gt;
&lt;li&gt;Declare a custom validator which extends &lt;code&gt;ClientSideValidations::Middleware::Base&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ClientSideValidations::Middleware&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Base&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i&lt;/span&gt;
            &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;super&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Create a new file
&lt;code&gt;public/javascripts/rails.validations.custom.js.coffee&lt;/code&gt; and add a
reference to it in your &lt;code&gt;application.js.coffee&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;        &lt;span class="c1"&gt;# app/assets/javascripts/application.js.coffee&lt;/span&gt;
        &lt;span class="c1"&gt;#= require rails.validations.custom&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add your client-side validator:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;        &lt;span class="c1"&gt;#public/javascripts/rails.validations.custom.js.coffee&lt;/span&gt;
        &lt;span class="n"&gt;clientSideValidations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vg"&gt;$.&lt;/span&gt;&lt;span class="n"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/validators/email.json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;invalid e-mail format&amp;#39;&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="assets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Assets&lt;/h2&gt;

&lt;p&gt;Use the &lt;a href="http://guides.rubyonrails.org/asset_pipeline.html"&gt;assets pipeline&lt;/a&gt; to leverage organization within
your application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reserve &lt;code&gt;app/assets&lt;/code&gt; for custom stylesheets, javascripts, or images.&lt;/li&gt;
&lt;li&gt;Third party code such as &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; or &lt;a href="http://twitter.github.com/bootstrap/"&gt;bootstrap&lt;/a&gt;
should be placed in &lt;code&gt;vendor/assets&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When possible, use gemified versions of assets (e.g. &lt;a href="https://github.com/rails/jquery-rails"&gt;jquery-rails&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="mailers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Mailers&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Name the mailers &lt;code&gt;SomethingMailer&lt;/code&gt;. Without the Mailer suffix it
isn't immediately apparent what's a mailer and which views are
related to the mailer.&lt;/li&gt;
&lt;li&gt;Provide both HTML and plain-text view templates.&lt;/li&gt;
&lt;li&gt;Enable errors raised on failed mail delivery in your development environment. The errors are disabled by default.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# config/environments/development.rb&lt;/span&gt;

    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raise_delivery_errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;smtp.gmail.com&lt;/code&gt; for SMTP server in the development environment
(unless you have local SMTP server, of course).&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# config/environments/development.rb&lt;/span&gt;

    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;smtp_settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;smtp.gmail.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;# more settings&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Provide default settings for the host name.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# config/environments/development.rb&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;default_url_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;local_ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:3000&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="c1"&gt;# config/environments/production.rb&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;default_url_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;your_site.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# in your mailer class&lt;/span&gt;
    &lt;span class="n"&gt;default_url_options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:host&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;your_site.com&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;If you need to use a link to your site in an email, always use the
&lt;code&gt;_url&lt;/code&gt;, not &lt;code&gt;_path&lt;/code&gt; methods. The &lt;code&gt;_url&lt;/code&gt; methods include the host
name and the &lt;code&gt;_path&lt;/code&gt; methods don't.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# wrong&lt;/span&gt;
    &lt;span class="no"&gt;You&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;always&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;course&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;here&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;course_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@course&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# right&lt;/span&gt;
    &lt;span class="no"&gt;You&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;always&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;course&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;here&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;course_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@course&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Format the from and to addresses properly. Use the following format:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# in your mailer class&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Your Name &amp;lt;info@your_site.com&amp;gt;&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Make sure that the e-mail delivery method for your test environment is set to &lt;code&gt;test&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# config/environments/test.rb&lt;/span&gt;

    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delivery_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The delivery method for development and production should be &lt;code&gt;smtp&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# config/environments/development.rb, config/environments/production.rb&lt;/span&gt;

    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delivery_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:smtp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="bundler"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Bundler&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Put gems used only for development or testing in the appropriate group in the Gemfile.&lt;/li&gt;
&lt;li&gt;Use only established gems in your projects. If you're contemplating
on including some little-known gem you should do a careful review of
its source code first.&lt;/li&gt;
&lt;li&gt;OS-specific gems will by default result in a constantly changing &lt;code&gt;Gemfile.lock&lt;/code&gt;
for projects with multiple developers using different operating systems.
Add all OS X specific gems to a &lt;code&gt;darwin&lt;/code&gt; group in the Gemfile, and all Linux
specific gems to a &lt;code&gt;linux&lt;/code&gt; group:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# Gemfile&lt;/span&gt;
    &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:darwin&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rb-fsevent&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;growl&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:linux&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rb-inotify&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;To require the appropriate gems in the right environment, add the
following to `config/application.rb`:
&lt;/code&gt;&lt;/pre&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;RUBY_PLATFORM&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/(linux|darwin)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;
    &lt;span class="no"&gt;Bundler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Do not remove the &lt;code&gt;Gemfile.lock&lt;/code&gt; from version control. This is not
some randomly generated file - it makes sure that all of your team
members get the same gem versions when they do a &lt;code&gt;bundle install&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="priceless"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Priceless Gems&lt;/h2&gt;

&lt;p&gt;One of the most important programming principles is "Don't reinvent
the wheel!". If you're faced with a certain task you should always
look around a bit for existing solutions, before unrolling your
own. Here's a list of some "priceless" gems (all of them Rails 3.1
compliant) that are useful in many Rails projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rspec/rspec-rails"&gt;rspec-rails&lt;/a&gt; - RSpec is a
replacement for Test::MiniTest. I cannot recommend highly enough
RSpec. rspec-rails provides Rails integration for RSpec.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cucumber/cucumber-rails"&gt;cucumber-rails&lt;/a&gt; -
Cucumber is the premium tool to develop feature tests in
Ruby. cucumber-rails provides Rails integration for Cucumber.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://haml-lang.com"&gt;haml&lt;/a&gt; - HAML is a concise templating language, considered by many
(including yours truly) to be far superior to Erb.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/indirect/haml-rails"&gt;haml-rails&lt;/a&gt; - haml-rails
provides Rails integration for Haml.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://slim-lang.com"&gt;slim&lt;/a&gt; - Slim is a concise templating
language, considered by many far superior to HAML (not to mention
Erb). The only thing stopping me from using Slim massively is the
lack of good support in major editors/IDEs. Its performance is
phenomenal.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/plataformatec/simple_form"&gt;simple_form&lt;/a&gt; - once you've used simple_form (or formtastic)
you'll never want to hear about Rails's default forms. It has a
great DSL for building forms and no opinion on markup.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fabricationgem.org/"&gt;fabrication&lt;/a&gt; - a great fixture
replacement (editor's choice).&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thoughtbot/factory_girl"&gt;factory_girl&lt;/a&gt; - an
alternative to fabrication. Nice and mature fixture
replacement. Spiritual ancestor of fabrication.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/notahat/machinist"&gt;machinist&lt;/a&gt; - Fixtures aren't
fun. Machinist is.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://faker.rubyforge.org/"&gt;faker&lt;/a&gt; - handy gem to generate dummy data (names, addresses, etc).&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/guard/guard"&gt;guard&lt;/a&gt; - fantastic gem that monitors file changes and invokes
tasks based on them. Loaded with lots of useful extension. Far
superior to autotest and watchr.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/timcharper/spork"&gt;spork&lt;/a&gt; - A DRb server for
testing frameworks (RSpec / Cucumber currently) that forks before
each run to ensure a clean testing state. Simply put it preloads a
lot of test environment and as consequence the startup time of your
tests in greatly decreased. Absolute must have!&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/colszowka/simplecov"&gt;simplecov&lt;/a&gt; - code coverage tool. Unlike RCov it's fully
compatible with Ruby 1.9. Generates great reports. Must have!&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/fguillen/simplecov-rcov"&gt;simplecov-rcov&lt;/a&gt; - RCov formatter for SimpleCov. Useful if you're
trying to use SimpleCov with the Hudson contininous integration
server.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jnicklas/capybara"&gt;capybara&lt;/a&gt; - Capybara aims to
simplify the process of integration testing Rack applications, such
as Rails, Sinatra or Merb. Capybara simulates how a real user would
interact with a web application. It is agnostic about the driver
running your tests and currently comes with Rack::Test and Selenium
support built in. HtmlUnit, WebKit and env.js are supported through
external gems. Works great in combination with RSpec &amp;amp; Cucumber.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/plataformatec/devise"&gt;devise&lt;/a&gt; - Devise is
full-featured authentication solution for Rails applications. In
most cases it's preferable to use devise to unrolling your custom
authentication solution.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jnicklas/carrierwave"&gt;carrierwave&lt;/a&gt; - the
ultimate file upload solution for Rails. Support both local and
cloud storage for the uploaded files (and many other cool
things). Integrates great with ImageMagick for image post-processing.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amatsuda/kaminari"&gt;kaminari&lt;/a&gt; - Great paginating solution.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pauldix/feedzirra"&gt;feedzirra&lt;/a&gt; - Very fast and flexible RSS/Atom feed parser.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sunspot/sunspot"&gt;sunspot&lt;/a&gt; - SOLR powered
  full-text search engine.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bcardarella/client_side_validations"&gt;client_side_validations&lt;/a&gt; - Fantastic gem
that automatically creates JavaScript client-side validations from
your existing server-side model validations. Highly recommended!&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sferik/rails_admin"&gt;rails_admin&lt;/a&gt; - With Rails Admin the creating of admin interface
for your Rails app is child's play. You get a nice dashboard, CRUD
UI and lots more. Very flexible and customizable.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This list is not exhaustive and other gems might be added to it along
the road. All of the gems on the list are field tested, have active
development and community and are known to be of good code quality.&lt;/p&gt;

&lt;p&gt;&lt;a name="flawed"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Flawed Gems&lt;/h2&gt;

&lt;p&gt;This is a list of gems that are either problematic or superseded by
other gems. You should avoid using them in your projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://rmagick.rubyforge.org/"&gt;rmagick&lt;/a&gt; - this gem is notorious for its memory consumption. Use
&lt;a href="https://github.com/probablycorey/mini_magick"&gt;minimagick&lt;/a&gt; instead.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.zenspider.com/ZSS/Products/ZenTest/"&gt;autotest&lt;/a&gt; - old solution for running tests automatically. Far
inferior to guard and &lt;a href="https://github.com/mynyml/watchr"&gt;watchr&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/relevance/rcov"&gt;rcov&lt;/a&gt; - code coverage tool, not
compatible with Ruby 1.9. Use SimpleCov instead.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cowboyd/therubyracer"&gt;therubyracer&lt;/a&gt; - the use of
this gem in production is strongly discouraged as it uses a very large amount of
memory.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This list is also a work in progress. Please, let me know if you know
other popular, but flawed gems.&lt;/p&gt;

&lt;p&gt;&lt;a name="processes"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Managing processes&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If your projects depends on various external processes use
&lt;a href="https://github.com/ddollar/foreman"&gt;foreman&lt;/a&gt; to manage them.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="testing"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Testing Rails applications&lt;/h1&gt;

&lt;p&gt;The best approach to implementing new features is probably the BDD
approach. You start out by writing some high level feature tests
(generally written using Cucumber), then you use these tests to drive
out the implementation of the feature. First you write view specs for
the feature and use those specs to create the relevant
views. Afterwards you create the specs for the controller(s) that will
be feeding data to the views and use those specs to implement the
controller. Finally you implement the models specs and the models
themselves.&lt;/p&gt;

&lt;p&gt;&lt;a name="cucumber"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Cucumber&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tag your pending scenarios with &lt;code&gt;@wip&lt;/code&gt; (work in progress).  These
scenarios will not be taken into account and will not be marked as
failing.  When finishing the work on a pending scenario and
implementing the functionality it tests, the tag &lt;code&gt;@wip&lt;/code&gt; should be
removed in order to include this scenario in the test suite.&lt;/li&gt;
&lt;li&gt;Setup your default profile to exclude the scenarios tagged with
&lt;code&gt;@javascript&lt;/code&gt;.  They are testing using the browser and disabling them
is recommended to increase the regular scenarios execution speed.&lt;/li&gt;
&lt;li&gt;Setup a separate profile for the scenarios marked with &lt;code&gt;@javascript&lt;/code&gt; tag.

&lt;ul&gt;
&lt;li&gt;The profiles can be configured in the &lt;code&gt;cucumber.yml&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# definition of a profile:&lt;/span&gt;
    &lt;span class="n"&gt;profile_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="vi"&gt;@tag_name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A profile is run with the command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cucumber -p profile_name&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If using &lt;a href="http://fabricationgem.org/"&gt;fabrication&lt;/a&gt; for fixtures
replacement, use the predefined
&lt;a href="http://fabricationgem.org/#!cucumber-steps"&gt;fabrication steps&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;Do not use the old &lt;code&gt;web_steps.rb&lt;/code&gt; step definitions!
&lt;a href="http://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off"&gt;The web steps were removed from the latest version of Cucumber.&lt;/a&gt; Their
usage leads to the creation of verbose scenarios that do not properly
reflect the application domain.&lt;/li&gt;
&lt;li&gt;When checking for the presence of an element with visible text
(link, button, etc.) check for the text, not the element id. This
can detect problems with the i18n.&lt;/li&gt;
&lt;li&gt;Create separate features for different functionality regarding the same kind of objects:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="no"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Articles&lt;/span&gt;
    &lt;span class="c1"&gt;# ... feature  implementation ...&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="no"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="no"&gt;Editing&lt;/span&gt;
    &lt;span class="c1"&gt;# ... feature  implementation ...&lt;/span&gt;

    &lt;span class="no"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="no"&gt;Publishing&lt;/span&gt;
    &lt;span class="c1"&gt;# ... feature  implementation ...&lt;/span&gt;

    &lt;span class="no"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="no"&gt;Search&lt;/span&gt;
    &lt;span class="c1"&gt;# ... feature  implementation ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Each feature has three main components

&lt;ul&gt;
&lt;li&gt;Title&lt;/li&gt;
&lt;li&gt;Narrative - a short explanation what the feature is about.&lt;/li&gt;
&lt;li&gt;Acceptance criteria - the set of scenarios each made up of individual steps.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The most common format is known as the Connextra format.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="no"&gt;In&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;benefit&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stakeholder&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="no"&gt;Wants&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;feature&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This format is the most common but is not required, the narrative can
be free text depending on the complexity of the feature.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Scenario Outlines freely to keep the scenarios DRY.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="no"&gt;Scenario&lt;/span&gt; &lt;span class="no"&gt;Outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="n"&gt;cannot&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;invalid&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;
      &lt;span class="no"&gt;When&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;try&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;email&amp;gt;&amp;quot;&lt;/span&gt;
      &lt;span class="no"&gt;Then&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;see&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;error&amp;gt;&amp;quot;&lt;/span&gt;

    &lt;span class="no"&gt;Examples&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="no"&gt;The&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;invalid&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The steps for the scenarios are in &lt;code&gt;.rb&lt;/code&gt; files under the
&lt;code&gt;step_definitions&lt;/code&gt; directory. The naming convention for the steps file
is &lt;code&gt;[description]_steps.rb&lt;/code&gt;.  The steps can be separated into
different files based on different criterias. It is possible to have
one steps file for each feature (&lt;code&gt;home_page_steps.rb&lt;/code&gt;).  There also
can be one steps file for all features for a particular object
(&lt;code&gt;articles_steps.rb&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Use multiline step arguments to avoid repetition&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="no"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;
      &lt;span class="no"&gt;Given&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;am&lt;/span&gt; &lt;span class="n"&gt;logged&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;John Doe&amp;quot;&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;user@test.com&amp;quot;&lt;/span&gt;
      &lt;span class="no"&gt;When&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;go&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;my&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;
      &lt;span class="no"&gt;Then&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;see&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;following&lt;/span&gt; &lt;span class="n"&gt;information&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="no"&gt;First&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="no"&gt;John&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="no"&gt;Last&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="no"&gt;Doe&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="vi"&gt;@test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

    &lt;span class="c1"&gt;# the step:&lt;/span&gt;
    &lt;span class="no"&gt;Then&lt;/span&gt;&lt;span class="sr"&gt; /^I should see the following information:$/&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;find_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use compound steps to keep the scenario DRY&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="no"&gt;When&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;subscribe&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;news&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Technical News&amp;quot;&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;

    &lt;span class="c1"&gt;# the step:&lt;/span&gt;
    &lt;span class="no"&gt;When&lt;/span&gt;&lt;span class="sr"&gt; /^I subscribe for news from the category &amp;quot;([^&amp;quot;]*)&amp;quot;$/&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="sx"&gt;%Q{&lt;/span&gt;
&lt;span class="sx"&gt;        When I go to the news categories page&lt;/span&gt;
&lt;span class="sx"&gt;        And I select the category &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sx"&gt;&lt;/span&gt;
&lt;span class="sx"&gt;        And I click the button &amp;quot;Subscribe for this category&amp;quot;&lt;/span&gt;
&lt;span class="sx"&gt;        And I confirm the subscription&lt;/span&gt;
&lt;span class="sx"&gt;      }&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Always use the Capybara negative matchers instead of should_not with positive,
they will retry the match for given timeout allowing you to test ajax actions.
&lt;a href="https://github.com/jnicklas/capybara"&gt;See Capybara's README for more explanation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="rspec"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;RSpec&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use just one expectation per example.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;ArticlesController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;

      &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;GET new&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;assigns new article and renders the new article template&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="ss"&gt;:new&lt;/span&gt;
          &lt;span class="n"&gt;assigns&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be_a_new&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;
          &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt; &lt;span class="ss"&gt;:new&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;ArticlesController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;

      &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;GET new&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;assigns a new article&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="ss"&gt;:new&lt;/span&gt;
          &lt;span class="n"&gt;assigns&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be_a_new&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;renders the new article template&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="ss"&gt;:new&lt;/span&gt;
          &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt; &lt;span class="ss"&gt;:new&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Make heavy use of &lt;code&gt;describe&lt;/code&gt; and &lt;code&gt;context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Name the &lt;code&gt;describe&lt;/code&gt; blocks as follows:

&lt;ul&gt;
&lt;li&gt;use "description" for non-methods&lt;/li&gt;
&lt;li&gt;use pound "#method" for instance methods&lt;/li&gt;
&lt;li&gt;use dot ".method" for class methods&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summary&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# the spec...&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;
      &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#summary&amp;#39;&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.latest&amp;#39;&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;a href="http://fabricationgem.org/"&gt;fabricators&lt;/a&gt; to create test
objects.&lt;/li&gt;
&lt;li&gt;Make heavy use of mocks and stubs&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# mocking a model&lt;/span&gt;
    &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# stubbing a method&lt;/span&gt;
    &lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:find&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;When mocking a model, use the &lt;code&gt;as_null_object&lt;/code&gt; method. It tells the
output to listen only for messages we expect and ignore any other
messages.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_null_object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;let&lt;/code&gt; blocks instead of &lt;code&gt;before(:all)&lt;/code&gt; blocks to create data for
the spec examples. &lt;code&gt;let&lt;/code&gt; blocks get lazily evaluated.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# use this:&lt;/span&gt;
    &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# ... instead of this:&lt;/span&gt;
    &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:each&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="vi"&gt;@article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;subject&lt;/code&gt; when possible&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;is not published on creation&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;be_published&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;specify&lt;/code&gt; if possible. It is a synonym of &lt;code&gt;it&lt;/code&gt; but is more readable when there is no docstring.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="vi"&gt;@article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;is not published on creation&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="vi"&gt;@article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;be_published&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;be_published&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;its&lt;/code&gt; when possible&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;has the current date as creation date&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;creation_date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;its&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:creation_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="rspec_views"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Views&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The directory structure of the view specs &lt;code&gt;spec/views&lt;/code&gt; matches the
one in &lt;code&gt;app/views&lt;/code&gt;. For example the specs for the views in
&lt;code&gt;app/views/users&lt;/code&gt; are placed in &lt;code&gt;spec/views/users&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The naming convention for the view specs is adding &lt;code&gt;_spec.rb&lt;/code&gt; to the
view name, for example the view &lt;code&gt;_form.html.haml&lt;/code&gt; has a
corresponding spec &lt;code&gt;_form.html.haml_spec.rb&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec_helper.rb&lt;/code&gt; need to be required in each view spec file.&lt;/li&gt;
&lt;li&gt;The outer &lt;code&gt;describe&lt;/code&gt; block uses the path to the view without the
&lt;code&gt;app/views&lt;/code&gt; part. This is used by the &lt;code&gt;render&lt;/code&gt; method when it is
called without arguments.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# spec/views/articles/new.html.haml_spec.rb&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;spec_helper&amp;#39;&lt;/span&gt;

    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;articles/new.html.haml&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Always mock the models in the view specs. The purpose of the view is
only to display information.&lt;/li&gt;
&lt;li&gt;The method &lt;code&gt;assign&lt;/code&gt; supplies the instance variables which the view
uses and are supplied by the controller.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# spec/views/articles/edit.html.haml_spec.rb&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;articles/edit.html.haml&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;renders the form for a new article creation&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;mock_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_new_record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_null_object&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt;
      &lt;span class="n"&gt;rendered&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;articles_path&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;input&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;submit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Prefer the capybara negative selectors over should_not with the positive.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;have_selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;input&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;submit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;have_xpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tr&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_no_selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;input&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;submit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_no_xpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tr&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;When a view uses helper methods, these methods need to be
stubbed. Stubbing the helper methods is done on the &lt;code&gt;template&lt;/code&gt;
object:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# app/helpers/articles_helper.rb&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ArticlesHelper&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;formatted_date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# app/views/articles/show.html.haml&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Published at: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;formatted_date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;published_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

    &lt;span class="c1"&gt;# spec/views/articles/show.html.haml_spec.rb&lt;/span&gt;
    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;articles/show.html.html&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;displays the formatted date of article publishing&amp;#39;&lt;/span&gt;
        &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2012&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;01&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:formatted_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;published_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;01.01.2012&amp;#39;&lt;/span&gt;

        &lt;span class="n"&gt;render&lt;/span&gt;
        &lt;span class="n"&gt;rendered&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Published at: 01.01.2012&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The helpers specs are separated from the view specs in the &lt;code&gt;spec/helpers&lt;/code&gt; directory.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="rspec_controllers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Controllers&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mock the models and stub their methods. Testing the controller should not depend on the model creation.&lt;/li&gt;
&lt;li&gt;Test only the behaviour the controller should be responsible about:

&lt;ul&gt;
&lt;li&gt;Execution of particular methods&lt;/li&gt;
&lt;li&gt;Data returned from the action - assigns, etc.&lt;/li&gt;
&lt;li&gt;Result from the action - template render, redirect, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;        &lt;span class="c1"&gt;# Example of a commonly used controller spec&lt;/span&gt;
        &lt;span class="c1"&gt;# spec/controllers/articles_controller_spec.rb&lt;/span&gt;
        &lt;span class="c1"&gt;# We are interested only in the actions the controller should perform&lt;/span&gt;
        &lt;span class="c1"&gt;# So we are mocking the model creation and stubbing its methods&lt;/span&gt;
        &lt;span class="c1"&gt;# And we concentrate only on the things the controller should do&lt;/span&gt;

        &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;ArticlesController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="c1"&gt;# The model will be used in the specs for all methods of the controller&lt;/span&gt;
          &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mock_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;POST create&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;creates a new article with the given attributes&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
              &lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;The New Article Title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;The New Article Title&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;

            &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;saves the article&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
              &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:save&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;

            &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;redirects to the Articles index&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
              &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:save&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;
              &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;redirect_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;index&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use context when the controller action has different behaviour depending on the received params.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# A classic example for use of contexts in a controller spec is creation or update when the object saves successfully or not.&lt;/span&gt;

    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;ArticlesController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mock_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;POST create&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;creates a new article with the given attributes&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="no"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;The New Article Title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;The New Article Title&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;saves the article&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:save&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;when the article saves successfully&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:save&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;sets a flash[:notice] message&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;
            &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:notice&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;The article was saved successfully.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;redirects to the Articles index&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;redirect_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;index&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;when the article fails to save&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:save&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;assigns @article&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;
            &lt;span class="n"&gt;assigns&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be_eql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;re-renders the &amp;quot;new&amp;quot; template&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;new&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="rspec_models"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Models&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Do not mock the models in their own specs.&lt;/li&gt;
&lt;li&gt;Use fabrication to make real objects.&lt;/li&gt;
&lt;li&gt;It is acceptable to mock other models or child objects.&lt;/li&gt;
&lt;li&gt;Create the model for all examples in the spec to avoid duplication.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;
      &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add an example ensuring that the fabricated model is valid.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;
      &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;is valid with valid attributes&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be_valid&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add a separate &lt;code&gt;describe&lt;/code&gt; for each attribute which has validations.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;
      &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#title&amp;#39;&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;is required&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
          &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;be_valid&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;When testing uniqueness of a model attribute, name the other object &lt;code&gt;another_object&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Article&lt;/span&gt;
      &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#title&amp;#39;&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;is unique&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;another_article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;another_article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;be_valid&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="rspec_mailers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Mailers&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The model in the mailer spec should be mocked. The mailer should not depend on the model creation.&lt;/li&gt;
&lt;li&gt;The mailer spec should verify that:

&lt;ul&gt;
&lt;li&gt;the subject is correct&lt;/li&gt;
&lt;li&gt;the receiver e-mail is correct&lt;/li&gt;
&lt;li&gt;the e-mail is sent to the right e-mail address&lt;/li&gt;
&lt;li&gt;the e-mail contains the required information&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;     &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;SubscriberMailer&lt;/span&gt;
       &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:subscriber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;mock_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Subscription&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;johndoe@test.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;John Doe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

       &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;successful registration email&amp;#39;&lt;/span&gt;
         &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;SubscriptionMailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;successful_registration_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

         &lt;span class="n"&gt;its&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:subject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Successful Registration!&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="n"&gt;its&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;info@your_site.com&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="n"&gt;its&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;subscriber&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

         &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;contains the subscriber name&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
           &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encoded&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subscriber&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="k"&gt;end&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="rspec_uploaders"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Uploaders&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What we can test about an uploader is whether the images are resized correctly.
Here is a sample spec of a &lt;a href="https://github.com/jnicklas/carrierwave"&gt;carrierwave&lt;/a&gt; image uploader:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# rspec/uploaders/person_avatar_uploader_spec.rb&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;spec_helper&amp;#39;&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;carrierwave/test/matchers&amp;#39;&lt;/span&gt;

    &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;PersonAvatarUploader&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;CarrierWave&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Test&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Matchers&lt;/span&gt;

      &lt;span class="c1"&gt;# Enable images processing before executing the examples&lt;/span&gt;
      &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="no"&gt;UserAvatarUploader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_processing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# Create a new uploader. The model is mocked as the uploading and resizing images does not depend on the model creation.&lt;/span&gt;
      &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:each&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="vi"&gt;@uploader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PersonAvatarUploader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mock_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_null_object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@uploader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path_to_file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# Disable images processing after executing the examples&lt;/span&gt;
      &lt;span class="n"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="no"&gt;UserAvatarUploader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_processing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# Testing whether image is no larger than given dimensions&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;the default version&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;scales down an image to be no larger than 256 by 256 pixels&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="vi"&gt;@uploader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be_no_larger_than&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# Testing whether image has the exact dimensions&lt;/span&gt;
      &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;the thumb version&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;scales down an image to be exactly 64 by 64 pixels&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="vi"&gt;@uploader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;thumb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_dimensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="reading"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Further Reading&lt;/h1&gt;

&lt;p&gt;There are a few excellent resources on Rails style, that you should
consider if you have time to spare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://tr3w.com/"&gt;The Rails 3 Way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://guides.rubyonrails.org/"&gt;Ruby on Rails Guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pragprog.com/book/achbd/the-rspec-book"&gt;The RSpec Book&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="contributing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Contributing&lt;/h1&gt;

&lt;p&gt;Nothing written in this guide is set in stone. It's my desire to work
together with everyone interested in Rails coding style, so that we could
ultimately create a resource that will be beneficial to the entire Ruby
community.&lt;/p&gt;

&lt;p&gt;Feel free to open tickets or send pull requests with improvements. Thanks in
advance for your help!&lt;/p&gt;

&lt;p&gt;&lt;a name="spreadtheword"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Spread the Word&lt;/h1&gt;

&lt;p&gt;A community-driven style guide is of little use to a community that
doesn't know about its existence. Tweet about the guide, share it with
your friends and colleagues. Every comment, suggestion or opinion we
get makes the guide just a little bit better. And we want to have the
best possible guide, don't we?&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/12/12/rails-style-guide/</feedburner:origLink></entry>
 
 <entry>
   <title>Ruby Style Guide</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/yod64xa06jI/" />
   <updated>2011-12-10T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/12/10/ruby-style-guide</id>
   <content type="html">&lt;h1&gt;Prelude&lt;/h1&gt;

&lt;blockquote&gt;&lt;p&gt;This guide is copy from &lt;a href="http://localhost:4000/2011/12/10/ruby-style-guide/"&gt;bbatsov&lt;/a&gt;'s work.
Style is what separates the good from the great. &lt;br/&gt;
-- Bozhidar Batsov&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;One thing has always bothered me as Ruby developer - Python developers
have a great programming style reference
(&lt;a href="http://www.python.org/dev/peps/pep-0008/"&gt;PEP-8&lt;/a&gt;) and we never got
an official guide, documenting Ruby coding style and best
practices. And I do believe that style matters. I also believe that
such fine fellows, like us Ruby developers, should be quite capable to
produce this coveted document.&lt;/p&gt;

&lt;p&gt;This guide started its life as our internal company Ruby coding guidelines
(written by yours truly). At some point I decided that the work I was
doing might be interesting to members of the Ruby community in general
and that the world had little need for another internal company
guideline. But the world could certainly benefit from a
community-driven and community-sanctioned set of practices, idioms and
style prescriptions for Ruby programming.&lt;/p&gt;

&lt;p&gt;Since the inception of the guide I've received a lot of feedback from
members of the exceptional Ruby community around the world. Thanks for
all the suggestions and the support! Together we can make a resource
beneficial to each and every Ruby developer out there.&lt;/p&gt;

&lt;p&gt;By the way, if you're into Rails you might want to check out the
complementary
&lt;a href="https://github.com/bbatsov/rails-style-guide"&gt;Ruby on Rails 3 Style Guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Table of Contents&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#guide"&gt;The Ruby Style Guide&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#layout"&gt;Source Code Layout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#syntax"&gt;Syntax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#naming"&gt;Naming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#comments"&gt;Comments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#annotations"&gt;Annotations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#classes"&gt;Classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#exceptions"&gt;Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#collections"&gt;Collections&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#strings"&gt;Strings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#literals"&gt;Percent Literals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#misc"&gt;Miscellaneous&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design"&gt;Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#contributing"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#spreadtheword"&gt;Spread the word&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;The Ruby Style Guide&lt;/h1&gt;

&lt;p&gt;This Ruby style guide recommends best practices so that real-world Ruby
programmers can write code that can be maintained by other real-world Ruby
programmers. A style guide that reflects real-world usage gets used, and a
style guide that holds to an ideal that has been rejected by the people it is
supposed to help risks not getting used at all &amp;ndash; no matter how good it is.&lt;/p&gt;

&lt;p&gt;The guide is separated into several sections of related rules. I've
tried to add the rationale behind the rules (if it's omitted I've
assumed that is pretty obvious).&lt;/p&gt;

&lt;p&gt;I didn't come up with all the rules out of nowhere - they are mostly
based on my extensive career as a professional software engineer,
feedback and suggestions from members of the Ruby community and
various highly regarded Ruby programming resources, such as
&lt;a href="http://pragprog.com/book/ruby3/programming-ruby-1-9"&gt;"Programming Ruby 1.9"&lt;/a&gt;
and &lt;a href="http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177"&gt;"The Ruby Programming Language"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The guide is still a work in progress - some rules are lacking
examples, some rules don't have examples that illustrate them clearly
enough. In due time these issues will be addressed - just keep them in
mind for now.&lt;/p&gt;

&lt;p&gt;You can generate a PDF or an HTML copy of this guide using
&lt;a href="https://github.com/TechnoGate/transmuter"&gt;Transmuter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a name="layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Source Code Layout&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;Nearly everybody is convinced that every style but their own is
ugly and unreadable. Leave out the "but their own" and they're
probably right... &lt;br/&gt;
-- Jerry Coffin (on indentation)&lt;/p&gt;&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;UTF-8&lt;/code&gt; as the source file encoding.&lt;/li&gt;
&lt;li&gt;Use two &lt;strong&gt;spaces&lt;/strong&gt; per indentation level.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
      &lt;span class="n"&gt;do_something&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# bad - four spaces&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
        &lt;span class="n"&gt;do_something&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use Unix-style line endings. (*BSD/Solaris/Linux/OSX users are covered by default,
Windows users have to be extra careful.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you're using Git you might want to add the following
configuration setting to protect your project from Windows line
endings creeping in: &lt;code&gt;$ git config --global core.autocrlf true&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use spaces around operators, after commas, colons and semicolons, around &lt;code&gt;{&lt;/code&gt;
and before &lt;code&gt;}&lt;/code&gt;. Whitespace might be (mostly) irrelevant to the Ruby
interpreter, but its proper use is the key to writing easily
readable code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hi&amp;#39;&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;The only exception is when using the exponent operator:
&lt;/code&gt;&lt;/pre&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;No spaces after &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;[&lt;/code&gt; or before &lt;code&gt;]&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Indent &lt;code&gt;when&lt;/code&gt; as deep as &lt;code&gt;case&lt;/code&gt;. I know that many would disagree
with this one, but it's the style established in both the "The Ruby
Programming Language" and "Programming Ruby".&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;case&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Misty&amp;#39;&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Not again!&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Too long!&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;It&amp;#39;s too late&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;kind&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt;
           &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1850&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1889&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Blues&amp;#39;&lt;/span&gt;
           &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1890&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1909&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Ragtime&amp;#39;&lt;/span&gt;
           &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1910&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1929&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;New Orleans Jazz&amp;#39;&lt;/span&gt;
           &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1930&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1939&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Swing&amp;#39;&lt;/span&gt;
           &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1940&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1950&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Bebop&amp;#39;&lt;/span&gt;
           &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Jazz&amp;#39;&lt;/span&gt;
           &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use empty lines between &lt;code&gt;def&lt;/code&gt;s and to break up a method into logical
paragraphs.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
      &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manipulate!&lt;/span&gt;

      &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use RDoc and its conventions for API documentation.  Don't put an
empty line between the comment block and the &lt;code&gt;def&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keep lines fewer than 80 characters.&lt;/li&gt;
&lt;li&gt;Avoid trailing whitespace.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="syntax"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Syntax&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;def&lt;/code&gt; with parentheses when there are arguments. Omit the
parentheses when the method doesn't accept any arguments.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
     &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;

   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method_with_arguments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Never use &lt;code&gt;for&lt;/code&gt;, unless you know exactly why. Most of the time iterators
should be used instead. &lt;code&gt;for&lt;/code&gt; is implemented in terms of &lt;code&gt;each&lt;/code&gt; (so
you're adding a level of indirection), but with a twist - &lt;code&gt;for&lt;/code&gt;
doesn't introduce a new scope (unlike &lt;code&gt;each&lt;/code&gt;) and variables defined
in its block will be visible outside it.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Never use &lt;code&gt;then&lt;/code&gt; for multi-line &lt;code&gt;if/unless&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
      &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt;
      &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Favor the ternary operator(&lt;code&gt;?:&lt;/code&gt;) over &lt;code&gt;if/then/else/end&lt;/code&gt; constructs.
It's more common and obviously more concise.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;something_else&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;something_else&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use one expression per branch in a ternary operator. This
also means that ternary operators must not be nested. Prefer
&lt;code&gt;if/else&lt;/code&gt; constructs in these cases.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;some_condition&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nested_condition&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;nested_something&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nested_something_else&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;something_else&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt;
      &lt;span class="n"&gt;nested_condition&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;nested_something&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nested_something_else&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;something_else&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Never use &lt;code&gt;if x: ...&lt;/code&gt; - it is removed in Ruby 1.9. Use
the ternary operator instead.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;something_else&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;something_else&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Never use &lt;code&gt;if x; ...&lt;/code&gt;. Use the ternary operator instead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;when x then ...&lt;/code&gt; for one-line cases. The alternative syntax
&lt;code&gt;when x: ...&lt;/code&gt; is removed in Ruby 1.9.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Never use &lt;code&gt;when x; ...&lt;/code&gt;. See the previous rule.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;&amp;amp;&amp;amp;/||&lt;/code&gt; for boolean expressions, &lt;code&gt;and/or&lt;/code&gt; for control flow.  (Rule
of thumb: If you have to use outer parentheses, you are using the
wrong operators.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# boolean expression&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;some_other_condition&lt;/span&gt;
      &lt;span class="n"&gt;do_something&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# control flow&lt;/span&gt;
    &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;saved?&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Avoid multi-line &lt;code&gt;?:&lt;/code&gt; (the ternary operator), use &lt;code&gt;if/unless&lt;/code&gt; instead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Favor modifier &lt;code&gt;if/unless&lt;/code&gt; usage when you have a single-line
body. Another good alternative is the usage of control flow &lt;code&gt;and/or&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt;
      &lt;span class="n"&gt;do_something&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;do_something&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt;

    &lt;span class="c1"&gt;# another good option&lt;/span&gt;
    &lt;span class="n"&gt;some_condition&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;do_something&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Favor &lt;code&gt;unless&lt;/code&gt; over &lt;code&gt;if&lt;/code&gt; for negative conditions (or control
flow &lt;code&gt;or&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;do_something&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;some_condition&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;do_something&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;some_condition&lt;/span&gt;

    &lt;span class="c1"&gt;# another good option&lt;/span&gt;
    &lt;span class="n"&gt;some_condition&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;do_something&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Never use &lt;code&gt;unless&lt;/code&gt; with &lt;code&gt;else&lt;/code&gt;. Rewrite these with the positive case first.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;success?&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;failure&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;success&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;success?&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;success&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;failure&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Don't use parentheses around the condition of an &lt;code&gt;if/unless/while&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
      &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Omit parentheses around parameters for methods that are part of an
internal DSL (e.g. Rake, Rails, RSpec), methods that are with
"keyword" status in Ruby (e.g. &lt;code&gt;attr_reader&lt;/code&gt;, &lt;code&gt;puts&lt;/code&gt;) and attribute
access methods. Use parentheses around the arguments of all other
method invocations.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
      &lt;span class="kp"&gt;attr_reader&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;

      &lt;span class="c1"&gt;# omitted&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;temperance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Temperance&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;temperance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;

    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;temperance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;

    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Prefer &lt;code&gt;{...}&lt;/code&gt; over &lt;code&gt;do...end&lt;/code&gt; for single-line blocks.  Avoid using
&lt;code&gt;{...}&lt;/code&gt; for multi-line blocks (multiline chaining is always
ugly). Always use &lt;code&gt;do...end&lt;/code&gt; for "control flow" and "method
definitions" (e.g. in Rakefiles and certain DSLs).  Avoid &lt;code&gt;do...end&lt;/code&gt;
when chaining.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Bozhidar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Steve&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Sarah&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;S&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upcase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;S&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upcase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;Some will argue that multiline chaining would look OK with the use of {...}, but they should
ask themselves - it this code really readable and can't the blocks contents be extracted into
nifty methods.
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;Avoid &lt;code&gt;return&lt;/code&gt; where not required.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;some_arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;some_arr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;some_arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;some_arr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use spaces around the &lt;code&gt;=&lt;/code&gt; operator when assigning default values to method parameters:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="ss"&gt;:default&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg3&lt;/span&gt;&lt;span class="o"&gt;=[]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# do something...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# do something...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;While several Ruby books suggest the first style, the second is much more prominent
in practice (and arguably a bit more readable).
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;Avoid line continuation (\) where not required. In practice, avoid using
line continuations at all.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
             &lt;span class="mi"&gt;2&lt;/span&gt;

    &lt;span class="c1"&gt;# good (but still ugly as hell)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
             &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Using the return value of &lt;code&gt;=&lt;/code&gt; (an assignment) is ok.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/foo/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;||=&lt;/code&gt; freely to initialize variables.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# set name to Bozhidar, only if it&amp;#39;s nil or false&lt;/span&gt;
    &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Bozhidar&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Don't use &lt;code&gt;||=&lt;/code&gt; to initialize boolean variables. (Consider what
would happen if the current value happened to be &lt;code&gt;false&lt;/code&gt;.)&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad - would set enabled to true even if it was false&lt;/span&gt;
    &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Avoid using Perl-style special variables (like &lt;code&gt;$0-9&lt;/code&gt;, `$``,
etc. ). They are quite cryptic and their use in anything but
one-liner scripts is discouraged.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Never put a space between a method name and the opening parenthesis.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the first argument to a method begins with an open parenthesis,
always use parentheses in the method invocation. For example, write
&lt;code&gt;f((3 + 2) + 1)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always run the Ruby interpreter with the &lt;code&gt;-w&lt;/code&gt; option so it will warn
you if you forget either of the rules above!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="naming"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Naming&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;The only real difficulties in programming are cache invalidation and
naming things. &lt;br/&gt;
-- Phil Karlton&lt;/p&gt;&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;snake_case&lt;/code&gt; for methods and variables.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;CamelCase&lt;/code&gt; for classes and modules.  (Keep acronyms like HTTP,
RFC, XML uppercase.)&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;SCREAMING_SNAKE_CASE&lt;/code&gt; for other constants.&lt;/li&gt;
&lt;li&gt;The names of predicate methods (methods that return a boolean value)
should end in a question mark.
(i.e. &lt;code&gt;Array#empty?&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The names of potentially "dangerous" methods (i.e. methods that modify &lt;code&gt;self&lt;/code&gt; or the
arguments, &lt;code&gt;exit!&lt;/code&gt;, etc.) should end with an exclamation mark.&lt;/li&gt;
&lt;li&gt;When using &lt;code&gt;inject&lt;/code&gt; with short blocks, name the arguments &lt;code&gt;|a, e|&lt;/code&gt;
(accumulator, element).&lt;/li&gt;
&lt;li&gt;When defining binary operators, name the argument &lt;code&gt;other&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;+&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Prefer &lt;code&gt;map&lt;/code&gt; over &lt;em&gt;collect&lt;/em&gt;, &lt;code&gt;find&lt;/code&gt; over &lt;em&gt;detect&lt;/em&gt;, &lt;code&gt;select&lt;/code&gt; over
&lt;em&gt;find_all&lt;/em&gt;, &lt;code&gt;size&lt;/code&gt; over &lt;em&gt;length&lt;/em&gt;. This is not a hard requirement; if the
use of the alias enhances readability, it's ok to use it.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="comments"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Comments&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;Good code is its own best documentation. As you're about to add a
comment, ask yourself, "How can I improve the code so that this
comment isn't needed?" Improve the code and then document it to make
it even clearer. &lt;br/&gt;
-- Steve McConnell&lt;/p&gt;&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Write self-documenting code and ignore the rest of this section. Seriously!&lt;/li&gt;
&lt;li&gt;Comments longer than a word are capitalized and use punctuation. Use &lt;a href="http://en.wikipedia.org/wiki/Sentence_spacing"&gt;one
space&lt;/a&gt; after periods.&lt;/li&gt;
&lt;li&gt;Avoid superfluous comments.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# increments counter by one&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Keep existing comments up-to-date. No comment is better than an outdated
comment.&lt;/li&gt;
&lt;li&gt;Avoid writing comments to explain bad code. Refactor the code to
make it self-explanatory. (Do or do not - there is no try.)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="annotations"/&gt;&lt;/p&gt;

&lt;h2&gt;Annotations&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Annotations should usually be written on the line immediately above
the relevant code.&lt;/li&gt;
&lt;li&gt;The annotation keyword is followed by a colon and a space, then a note
describing the problem.&lt;/li&gt;
&lt;li&gt;If multiple lines are required to describe the problem, subsequent
lines should be indented two spaces after the &lt;code&gt;#&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;
      &lt;span class="c1"&gt;# FIXME: This has crashed occasionally since v3.2.1. It may&lt;/span&gt;
      &lt;span class="c1"&gt;#   be related to the BarBazUtil upgrade.&lt;/span&gt;
      &lt;span class="n"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:quux&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;In cases where the problem is so obvious that any documentation would
be redundant, annotations may be left at the end of the offending line
with no note. This usage should be the exception and not the rule.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;
      &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="c1"&gt;# OPTIMIZE&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;TODO&lt;/code&gt; to note missing features or functionality that should be
added at a later date.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;FIXME&lt;/code&gt; to note broken code that needs to be fixed.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;OPTIMIZE&lt;/code&gt; to note slow or inefficient code that may cause
performance problems.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;HACK&lt;/code&gt; to note code smells where questionable coding practices
were used and should be refactored away.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;REVIEW&lt;/code&gt; to note anything that should be looked at to confirm it
is working as intended. For example: &lt;code&gt;REVIEW: Are we sure this is how the
client does X currently?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use other custom annotation keywords if it feels appropriate, but be
sure to document them in your project's &lt;code&gt;README&lt;/code&gt; or similar.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="classes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Classes&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always supply a proper &lt;code&gt;to_s&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
      &lt;span class="kp"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last_name&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;
        &lt;span class="vi"&gt;@last_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#@first_name&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#@last_name&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use the &lt;code&gt;attr&lt;/code&gt; family of functions to define trivial accessors or
mutators.&lt;/li&gt;
&lt;li&gt;Consider adding factory methods to provide additional sensible ways
to create instances of a particular class.&lt;/li&gt;
&lt;li&gt;Prefer duck-typing over inheritance.&lt;/li&gt;
&lt;li&gt;Avoid the usage of class (&lt;code&gt;@@&lt;/code&gt;) variables due to their "nasty" behavior
in inheritance.&lt;/li&gt;
&lt;li&gt;Assign proper visibility levels to methods (&lt;code&gt;private&lt;/code&gt;, &lt;code&gt;protected&lt;/code&gt;)
in accordance with their intended usage. Don't go off leaving
everything &lt;code&gt;public&lt;/code&gt; (which is the default). After all we're coding
in &lt;em&gt;Ruby&lt;/em&gt; now, not in &lt;em&gt;Python&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Indent the &lt;code&gt;public&lt;/code&gt;, &lt;code&gt;protected&lt;/code&gt;, and &lt;code&gt;private&lt;/code&gt; methods as much the
method definitions they apply to. Leave one blank line above them.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeClass&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;public_method&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="kp"&gt;private&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;private_method&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;def self.method&lt;/code&gt; to define singleton methods. This makes the methods
more resistant to refactoring changes.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestClass&lt;/span&gt;
      &lt;span class="c1"&gt;# bad&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;TestClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some_method&lt;/span&gt;
        &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# good&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some_other_method&lt;/span&gt;
        &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# Also possible and convenient when you&lt;/span&gt;
      &lt;span class="c1"&gt;# have to define many singleton methods.&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;first_method&lt;/span&gt;
          &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;second_method_etc&lt;/span&gt;
          &lt;span class="c1"&gt;# body omitted&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="exceptions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Exceptions&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Don't suppress exceptions.&lt;/li&gt;
&lt;li&gt;Don't use exceptions for flow of control.&lt;/li&gt;
&lt;li&gt;Avoid rescuing the &lt;code&gt;Exception&lt;/code&gt; class.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="collections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Collections&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It's ok to use arrays as sets for a small number of elements.&lt;/li&gt;
&lt;li&gt;Prefer &lt;code&gt;%w&lt;/code&gt; to the literal array syntax when you need an array of
strings.&lt;/li&gt;
&lt;li&gt;Avoid the creation of huge gaps in arrays.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Set&lt;/code&gt; instead of &lt;code&gt;Array&lt;/code&gt; when dealing with lots of elements.&lt;/li&gt;
&lt;li&gt;Use symbols instead of strings as hash keys.&lt;/li&gt;
&lt;li&gt;Avoid the use of mutable object as hash keys.&lt;/li&gt;
&lt;li&gt;Use the new 1.9 literal hash syntax in preference to the hashrocket syntax.&lt;/li&gt;
&lt;li&gt;Rely on the fact that hashes in 1.9 are ordered.&lt;/li&gt;
&lt;li&gt;Never modify a collection while traversing it.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="strings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Strings&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prefer string interpolation instead of string concatenation:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="n"&gt;email_with_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;lt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;gt;&amp;#39;&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="n"&gt;email_with_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Prefer single-quoted strings when you don't need string interpolation or
special symbols such as &lt;code&gt;\t&lt;/code&gt;, &lt;code&gt;\n&lt;/code&gt;, &lt;code&gt;'&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Bozhidar&amp;quot;&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Bozhidar&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Don't use &lt;code&gt;{}&lt;/code&gt; around instance variables being interpolated into a
string.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
      &lt;span class="kp"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last_name&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;
        &lt;span class="vi"&gt;@last_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# bad&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@first_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@last_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# good&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#@first_name&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#@last_name&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Avoid using &lt;code&gt;String#+&lt;/code&gt; when you need to construct large data chunks.
Instead, use &lt;code&gt;String#&amp;lt;&amp;lt;&lt;/code&gt;. Concatenation mutates the string instance in-place
and is always faster than &lt;code&gt;String#+&lt;/code&gt;, which creates a bunch of new string objects.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# good and also fast&lt;/span&gt;
    &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;lt;h1&amp;gt;Page title&amp;lt;/h1&amp;gt;&amp;#39;&lt;/span&gt;

    &lt;span class="n"&gt;paragraphs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;paragraph&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;paragraph&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a name="literals"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Percent Literals&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;%w&lt;/code&gt; freely.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="no"&gt;STATES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w(draft open closed)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;%()&lt;/code&gt; for single-line strings which require both interpolation
and embedded double-quotes. For multi-line strings, prefer heredocs.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad (no interpolation needed)&lt;/span&gt;
    &lt;span class="sx"&gt;%(&amp;lt;div class=&amp;quot;text&amp;quot;&amp;gt;Some text&amp;lt;/div&amp;gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# should be &amp;#39;&amp;lt;div class=&amp;quot;text&amp;quot;&amp;gt;Some text&amp;lt;/div&amp;gt;&amp;#39;&lt;/span&gt;

    &lt;span class="c1"&gt;# bad (no double-quotes)&lt;/span&gt;
    &lt;span class="sx"&gt;%(This is &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;quality&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sx"&gt; style)&lt;/span&gt;
    &lt;span class="c1"&gt;# should be &amp;quot;This is #{quality} style&amp;quot;&lt;/span&gt;

    &lt;span class="c1"&gt;# bad (multiple lines)&lt;/span&gt;
    &lt;span class="sx"&gt;%(&amp;lt;div&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sx"&gt;&amp;lt;span class=&amp;quot;big&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;exclamation&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sx"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sx"&gt;&amp;lt;/div&amp;gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# should be a heredoc.&lt;/span&gt;

    &lt;span class="c1"&gt;# good (requires interpolation, has quotes, single line)&lt;/span&gt;
    &lt;span class="sx"&gt;%(&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;name&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sx"&gt;&amp;lt;/td&amp;gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;%r&lt;/code&gt; only for regular expressions matching &lt;em&gt;more than&lt;/em&gt; one '/' character.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# bad&lt;/span&gt;
    &lt;span class="sr"&gt;%r(\s+)&lt;/span&gt;

    &lt;span class="c1"&gt;# still bad&lt;/span&gt;
    &lt;span class="sr"&gt;%r(^/(.*)$)&lt;/span&gt;
    &lt;span class="c1"&gt;# should be /^\/(.*)$/&lt;/span&gt;

    &lt;span class="c1"&gt;# good&lt;/span&gt;
    &lt;span class="sr"&gt;%r(^/blog/2011/(.*)$)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Avoid &lt;code&gt;%q&lt;/code&gt;, &lt;code&gt;%Q&lt;/code&gt;, &lt;code&gt;%x&lt;/code&gt;, &lt;code&gt;%s&lt;/code&gt;, and &lt;code&gt;%W&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prefer &lt;code&gt;()&lt;/code&gt; as delimiters for all &lt;code&gt;%&lt;/code&gt; literals.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="misc"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Misc&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Write &lt;code&gt;ruby -w&lt;/code&gt; safe code.&lt;/li&gt;
&lt;li&gt;Avoid hashes as optional parameters. Does the method do too much?&lt;/li&gt;
&lt;li&gt;Avoid methods longer than 10 LOC (lines of code). Ideally, most methods will be shorter than
5 LOC. Empty lines do not contribute to the relevant LOC.&lt;/li&gt;
&lt;li&gt;Avoid parameter lists longer than three or four parameters.&lt;/li&gt;
&lt;li&gt;If you really have to, add "global" methods to Kernel and make them private.&lt;/li&gt;
&lt;li&gt;Use class instance variables instead of global variables.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;#bad&lt;/span&gt;
    &lt;span class="vg"&gt;$foo_bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="c1"&gt;#good&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
        &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:bar&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="no"&gt;Foo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Avoid &lt;code&gt;alias&lt;/code&gt; when &lt;code&gt;alias_method&lt;/code&gt; will do.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;OptionParser&lt;/code&gt; for parsing complex command line options and
&lt;code&gt;ruby -s&lt;/code&gt; for trivial command line options.&lt;/li&gt;
&lt;li&gt;Write for Ruby 1.9. Don't use legacy Ruby 1.8 constructs.

&lt;ul&gt;
&lt;li&gt;Use the new JavaScript literal hash syntax.&lt;/li&gt;
&lt;li&gt;Use the new lambda syntax.&lt;/li&gt;
&lt;li&gt;Methods like &lt;code&gt;inject&lt;/code&gt; now accept method names as arguments.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;      &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Avoid needless metaprogramming.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="design"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Design&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Code in a functional way, avoiding mutation when that makes sense.&lt;/li&gt;
&lt;li&gt;Do not mutate arguments unless that is the purpose of the method.&lt;/li&gt;
&lt;li&gt;Do not mess around in core classes when writing libraries. (Do not monkey
patch them.)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.erlang.se/doc/programming_rules.shtml#HDR11"&gt;Do not program
defensively.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Keep the code simple and subjective. Each method should have a single,
well-defined responsibility.&lt;/li&gt;
&lt;li&gt;Avoid more than three levels of block nesting.&lt;/li&gt;
&lt;li&gt;Don't overdesign. Overly complex solutions tend to be brittle and hard to
maintain.&lt;/li&gt;
&lt;li&gt;Don't underdesign. A solution to a problem should be as simple as
possible, but no simpler than that. Poor initial design can lead to a lot
of problems in the future.&lt;/li&gt;
&lt;li&gt;Be consistent. In an ideal world, be consistent with these guidelines.&lt;/li&gt;
&lt;li&gt;Use common sense.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name="contributing"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Contributing&lt;/h1&gt;

&lt;p&gt;Nothing written in this guide is set in stone. It's my desire to work
together with everyone interested in Ruby coding style, so that we could
ultimately create a resource that will be beneficial to the entire Ruby
community.&lt;/p&gt;

&lt;p&gt;Feel free to open tickets or send pull requests with improvements. Thanks in
advance for your help!&lt;/p&gt;

&lt;p&gt;&lt;a name="spreadtheword"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Spread the Word&lt;/h1&gt;

&lt;p&gt;A community-driven style guide is of little use to a community that
doesn't know about its existence. Tweet about the guide, share it with
your friends and colleagues. Every comment, suggestion or opinion we
get makes the guide just a little bit better. And we want to have the
best possible guide, don't we?&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/12/10/ruby-style-guide/</feedburner:origLink></entry>
 
 <entry>
   <title>Migrate Blog to Jekyll with Jekyll Extension</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/wtkv6dqg3N8/" />
   <updated>2011-12-09T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/12/09/migrate-blog-to-jekyll</id>
   <content type="html">&lt;p&gt;I'm happy to see you guys, I built my own rails blog system about 3 years ago, but long time no updates with my blog. Since known about &lt;a href="https://github.com/mojombo/jekyll"&gt;Jekyll&lt;/a&gt;, a simple, blog aware, static site generator, It's cool to build a blog using jekyll without databases, that's great for me to write blog articles useing markdown format.&lt;/p&gt;

&lt;p&gt;So I started to build my new blog system by Jekyll several days ago, but I got some problems about Jekyll extensions during the installation, with richard's help, it works, bye the way, you need to install the pyments for code highlight if you want to highlight your code. you can follow the &lt;a href="https://github.com/mojombo/jekyll/wiki"&gt;Jekyll Wiki&lt;/a&gt; to get forward.&lt;/p&gt;

&lt;p&gt;What I want for my blog system is not supported by default Jekyll, but I added some extensions according to &lt;a href="https://github.com/rfelix/my_jekyll_extensions"&gt;My Jekyll Extensions&lt;/a&gt;, It's really cool that we can build our categories section, monthly archive section, categroy page, monthly archive page without database now.&lt;/p&gt;

&lt;p&gt;You can clone my Jekyll blog system &lt;a href="https://github.com/jerryshen/hansay.com"&gt;hansay.com&lt;/a&gt; at &lt;a href="https://github.com/jerryshen/hansay.com"&gt;https://github.com/jerryshen/hansay.com&lt;/a&gt;.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/12/09/migrate-blog-to-jekyll/</feedburner:origLink></entry>
 
 <entry>
   <title>Deployment with RVM, nginx, and passenger for ruby on rails</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/3JkYMF0sWUw/" />
   <updated>2011-12-03T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/12/03/deployment-for-ubuntu-server-with-rvm-nginx-passenger-and-postgresql-for-ruby-on-rails</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;服务器系统:&lt;/strong&gt;   ubuntu server 11.10 64bit&lt;br/&gt;
&lt;strong&gt;案例服务器:&lt;/strong&gt;   Linode VPS 512系列&lt;/p&gt;

&lt;p&gt;租下vps, 选择所要的系统 ubuntu server 11.10 64bit, 我一直不喜欢直接用root来做部署, 所以我会创建一个具有sudo权限的用户来完成整个部署和操作, 下面以jerry为例:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  useradd jerry            # 添加用户'jerry'
$  passwd jerry             # 为'jerry'设置密码
$  gpasswd -a jerry sudo    # 将用户jerry添加进sudo组(sudo组是默认就存在的，所以不用创建)
$  cd /home &amp;amp;&amp;amp; mkdir jerry  # 为jerry创建工作目录
$  chown jerry /home/jerry  # 设置权限
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;添加jerry后可能是不是bash环境, 如果发现不是bash环境, 可以融过root用户将jerry的环境改成bash&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ usermod --shell=/bin/bash jerry
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;通过编辑&lt;code&gt;authorized_keys&lt;/code&gt;, 添加public key到jerry用户目录下, 这样以后ssh远程登录服务器就无须输入密码了&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  cd ~  
$  mkdir .ssh  &amp;amp;&amp;amp; cd .ssh  
$  vim authorized_keys      # 贴入public key
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来需要安装&lt;a href="http://beginrescueend.com/"&gt;RVM&lt;/a&gt;, 安装RVM前需要安装几个必要的packages&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  sudo apt-get install curl git-core libtool
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;然后安装rvm&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  bash &amp;lt; &amp;lt;(curl -s https://rvm.beginrescueend.com/install/rvm)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在 &lt;code&gt;~/.bashrc&lt;/code&gt; 中设置RVM的环境变量&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if [[ -s "$HOME/.rvm/scripts/rvm" ]]  ; then source "$HOME/.rvm/scripts/rvm" ; fi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在 &lt;code&gt;~.bash_profile&lt;/code&gt; 中引用 &lt;code&gt;.bashrc&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;推出终端重新进入, 你会发现RVM已经生效了&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  rvm notes  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;安装必要的packages&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  sudo apt-get install bison build-essential zlib1g zlib1g-dev libssl-dev libreadline-gplv2-dev libxml2-dev libxslt1-dev autoconf  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;安装完以上的packages后, 正式用rvm编译ruby 1.9.3, rvm会将ruby自动编译到当前用户目录的 &lt;code&gt;~/.rvm&lt;/code&gt; 下(非root用户).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  rvm install 1.9.3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;安装完ruby 1.9.3后, 我们可以把rvm ruby 1.9.3设置为默认&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  rvm --default ruby-1.9.3-p0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来就可以查看ruby 版本了&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  ruby -v
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;至此 Ruby 1.9.3编译已经完成&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;安装 Postgresql 数据库&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;首先需要确认当前用户 env的LANG是否为UTF8,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  env
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;看显示信息是否有 LANG=en_US.UTF8，如果没有,在 &lt;code&gt;/etc/profile&lt;/code&gt; 中加入环境变量:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export LANG=en_US.UTF8
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;之后退出终端再进入, 你的设置就生效了, 然后安装postgresql数据库, 以 ubuntu 11.10为例, 版本应该是 9.1&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  sudo apt-get install postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;切换到root用户下, 初始化postgresql用户和密码&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  su postgres -c psql postgres
$  ALTER USER postgres WITH PASSWORD 'postgres';
$  \q  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;其中 'postgres' 为要修改的密码&lt;/p&gt;

&lt;p&gt;编辑 &lt;code&gt;/etc/postgresql/9.1/main/pg_hba.conf&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Database administrative login by UNIX sockets
# local   all         postgres                        ident

# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD

# "local" is for Unix domain socket connections only
local   all         all                               md5 #ident
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5
# IPv6 local connections:
host    all         all         ::1/128               md5  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果不希望允许 postgres 使用密码登入的可以开启第2行 &lt;code&gt;# local all postgres ident&lt;/code&gt; 的注释&lt;/p&gt;

&lt;p&gt;编辑 &lt;code&gt;/etc/postgresql/9.1/main/postgresql.conf&lt;/code&gt;, 搜索 &lt;code&gt;# listen_addresses =&lt;/code&gt; 将其修改为&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;listen_addresses = 'localhost'    # which IP address(es) to listen on;  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果允许其他机器访问的请将 localhost 修改成 *&lt;/p&gt;

&lt;p&gt;重启数据库&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  /etc/init.d/postgresql restart
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;安装 Phusion Passenger&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ruby1.9.3安装好之后, 会自动带一个空的gemset, 切换到该gemset下并安装passenger&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rvm use 1.9.3@
$ gem install -V passenger   
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;安装 nginx 服务器&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;下载最新的stable version nginx&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  mkdir -p /home/jerry/opt/src &amp;amp;&amp;amp; cd /home/jerry/opt/src
$  wget http://nginx.org/download/nginx-1.0.10.tar.gz
$  tar xvf nginx-1.0.10.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;安装编译相关类库&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  sudo apt-get install libpcre3-dev  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;编译安装带有 passenger 模块的nginx&lt;/p&gt;

&lt;p&gt;使用 passenger 脚本 &lt;code&gt;passenger-install-nginx-module&lt;/code&gt; 编译 nginx&lt;/p&gt;

&lt;p&gt;选择 &lt;code&gt;2. No: I want to customize my Nginx installation. (for advanced users)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;输入 &lt;code&gt;src: /home/jerry/opt/src/nginx-1.0.10&lt;/code&gt; 和 &lt;code&gt;prefix: /home/jerry/opt/nginx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;添加编译参数并编译&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  --conf-path=/home/jerry/opt/etc/nginx/nginx.conf --with-http_gzip_static_module  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果还要启动其他编译参数请自行添加&lt;/p&gt;

&lt;p&gt;另外如果不想使用passenger自带脚本编译nginx, 也可以手工编译nginx时加入以下参数, 来启动passenger模块&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;--add-module='/home/jerry//opt/passenger/ext/nginx 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;配置 nginx&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;整理编译自动生成的配置文件&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  cd /home/jerry/opt/etc/nginx
$  mkdir /home/jerry/opt/etc/nginx/default
$  mv *.default default/
$  mkdir conf.d
$  mkdir sites-enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将 &lt;code&gt;/home/jerry/opt/etc/nginx/nginx.conf&lt;/code&gt; 替换为&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;user  jerry jerry;
worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;
    gzip  on;

    include conf.d/*.conf;
    include sites-enabled/*;
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;添加 gzip_static 模块配置, 编辑 &lt;code&gt;/home/jerry/opt/etc/nginx/conf.d/gzip_static.conf&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gzip_static on;
gzip_types text/css application/x-javascript;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;添加 Passneger 模块配置, 编辑 &lt;code&gt;/home/jerry/opt/etc/nginx/conf.d/passenger.conf&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;passenger_root /home/jerry/.rvm/gems/ruby-1.9.3-p0/gems/passenger-3.0.11;
passenger_ruby /home/jerry/.rvm/bin/ruby-1.9.3-p0;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将nginx的server配置链接到sites-enabled下&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  ln -s /home/jerry/apps/conf/nginx.conf /home/jerry/opt/etc/nginx/sites-enabled/default  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;编辑 &lt;code&gt;/home/jerry/apps/conf/nginx.conf&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;server{
  listen 80;
  server_name  demo.com www.demo.com;
  root /home/jerry/apps/demo/current/public;
  passenger_enabled on;

  location ~ ^/(images|javascripts|stylesheets)/  {
      root /home/jerry/apps/demo/current/public;
      expires 30d;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果需要配置 详细的配置信息, 请参考 &lt;a href="http://beginrescueend.com/"&gt;Nginx 文档&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;添加启动脚本 &lt;code&gt;/home/jerry/opt/etc/init.d/nginx&lt;/code&gt; 内容为&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#! /bin/sh

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

# PATH=/home/jerry/.rvm/gems/ruby-1.9.3-p0/bin:/bin:/home/jerry/.rvm/rubies/ruby-1.9.3-p0/bin:/home/jerry/.rvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
DAEMON=/home/jerry/opt/nginx/sbin/nginx
NAME=nginx
DESC=nginx
PIDFILE=/home/jerry/opt/nginx/logs/$NAME.pid

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /home/jerry/opt/etc/default/nginx ] ; then
    . /home/jerry/opt/etc/default/nginx
fi

set -e

. /lib/lsb/init-functions

test_nginx_config() {
    if $DAEMON -t; then
        return 0
    else
        return $?
    fi
}

case "$1" in
    start)
        echo -n "Starting $DESC: "
        test_nginx_config
        start-stop-daemon --start --quiet --pidfile $PIDFILE \
            --exec $DAEMON -- $DAEMON_OPTS || true
        echo "$NAME."
    ;;
    stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --quiet --pidfile $PIDFILE \
            --exec $DAEMON || true
        echo "$NAME."
    ;;
    restart|force-reload)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --quiet --pidfile \
            $PIDFILE --exec $DAEMON || true
        sleep 1
        test_nginx_config
        start-stop-daemon --start --quiet --pidfile \
            $PIDFILE --exec $DAEMON -- $DAEMON_OPTS || true
        echo "$NAME."
    ;;
    reload)
        echo -n "Reloading $DESC configuration: "
        test_nginx_config
        start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE \
           --exec $DAEMON || true
        echo "$NAME."
    ;;
    configtest)
        echo -n "Testing $DESC configuration: "
        if test_nginx_config; then
            echo "$NAME."
        else
            exit $?
        fi
    ;;
    status)
        status_of_proc -p $PIDFILE "$DAEMON" nginx &amp;amp;&amp;amp; exit 0 || exit $?
    ;;
    *)
        echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest}" &amp;gt;&amp;amp;2
        exit 1
    ;;
esac

exit 0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;切换到root用户, 设置nginx的随机服务启动&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$  chmod +x /home/jerry/opt/etc/init.d/nginx
$  ln -s /home/jerry/opt/etc/init.d/nginx /etc/init.d/nginx
$  update-rc.d nginx defaults
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;到这里nginx的配置已经完成，接下来你就可以将项目发布到服务器了.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/12/03/deployment-for-ubuntu-server-with-rvm-nginx-passenger-and-postgresql-for-ruby-on-rails/</feedburner:origLink></entry>
 
 <entry>
   <title>Using Nested Form with Simple Form</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/4sWy0pEMveM/" />
   <updated>2011-11-30T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/11/30/using-nested-form-with-simple-form</id>
   <content type="html">&lt;p&gt;I would like to introduce you guys a Rails gem for conveniently manage multiple nested models in a single form.
It does so in an unobtrusive way through jQuery.&lt;/p&gt;

&lt;p&gt;For now this gem only works with Rails 3.&lt;/p&gt;

&lt;p&gt;Add it to your Gemfile then run &lt;code&gt;bundle&lt;/code&gt; to install it.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;nested_form&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:git&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;git://github.com/ryanb/nested_form.git&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;For Rails 3.1, the only thing you have to do is just require the js file in your &lt;code&gt;application.js&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# application.js&lt;/span&gt;&lt;span class="sr"&gt;&lt;/span&gt;
&lt;span class="sr"&gt;    //= require jquery&lt;/span&gt;
&lt;span class="sr"&gt;    /&lt;/span&gt;&lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="n"&gt;jquery_ujs&lt;/span&gt;&lt;span class="sr"&gt;&lt;/span&gt;
&lt;span class="sr"&gt;    //= require nested_form&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;So we can get started with nested form now, we can imagine that we have a Product model that &lt;code&gt;has_many :photos&lt;/code&gt;.
To be able to use this function, you need to add some configuration to your Product model, ad we have Photo model
which is to store the photos.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Photo&lt;/span&gt;
      &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Document&lt;/span&gt;

      &lt;span class="n"&gt;mount_uploader&lt;/span&gt; &lt;span class="ss"&gt;:data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;PhotoUploader&lt;/span&gt;

      &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;

      &lt;span class="n"&gt;embedded_in&lt;/span&gt; &lt;span class="ss"&gt;:product&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;
      &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Document&lt;/span&gt;
      &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Timestamps&lt;/span&gt;

      &lt;span class="n"&gt;embedded_many&lt;/span&gt; &lt;span class="ss"&gt;:photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cascade_callbacks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

      &lt;span class="n"&gt;accepts_nested_attributes_for&lt;/span&gt; &lt;span class="ss"&gt;:photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="n"&gt;reject_if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;blank?&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                                    &lt;span class="n"&gt;allow_destroy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If you don't have the &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; settings for photos, you'll get a Missing Block Error.&lt;/p&gt;

&lt;p&gt;We also use SimpleForm to make our form simpler, in this Git repo, It was implemented to use &lt;code&gt;simple_nested_form_for&lt;/code&gt; for SimpleForm support. But this feature is not yet in a Gem release, so you can use this git repo.&lt;/p&gt;

&lt;p&gt;Here is the form.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;simple_nested_form_for&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:url&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;products_path&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;
      
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;simple_fields_for&lt;/span&gt; &lt;span class="ss"&gt;:photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;photo&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;label_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_tag&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;label_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;link_to_remove&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;delete this image&amp;#39;&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="ss"&gt;:data_cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:hidden&lt;/span&gt;
            
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;simple_fields_for&lt;/span&gt; &lt;span class="ss"&gt;:photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="ss"&gt;:data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:file&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="ss"&gt;:data_cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:hidden&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;link_to_remove&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;remove&amp;#39;&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;link_to_add&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Add&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:photos&lt;/span&gt;

      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Save changes&amp;#39;&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;button_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Reset&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;reset&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This gem is produced by Ryanb, many thanks.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/11/30/using-nested-form-with-simple-form/</feedburner:origLink></entry>
 
 <entry>
   <title>Getting Started with RSpec</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/1qBuzOjyrYg/" />
   <updated>2011-11-28T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/11/28/getting-started-with-rspec</id>
   <content type="html">&lt;p&gt;One of the reasons that I love rails is the awesome test frameworks. Here’s an introduction for those of you interested in getting started with RSpec.&lt;/p&gt;

&lt;p&gt;Everyone may know Behaviour Driven Development, It's an Agile development process that comprises aspects of Acceptance Test Driven Planning, Domain Driven Design and Test Driven Development. RSpec is a BDD tool aimed at TDD in the context of BDD.&lt;/p&gt;

&lt;p&gt;Here is my gemfile.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;#gemfile&lt;/span&gt;
    
    &lt;span class="c1"&gt;# mongo support&lt;/span&gt;
    &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;mongo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.3.1&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;mongoid&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 2.3.3&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;bson&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.3.1&amp;#39;&lt;/span&gt;
    &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;bson_ext&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.3.1&amp;#39;&lt;/span&gt;
    
    &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:development&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;machinist&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 2.0.0.beta2&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;machinist_mongo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="ss"&gt;:git&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;https://github.com/nmerouze/machinist_mongo.git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:require&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;machinist/mongoid&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:branch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;machinist2&amp;#39;&lt;/span&gt;  &lt;span class="c1"&gt;# you need to add this if you are using mongoid&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;database_cleaner&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 0.6.7&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ffaker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.8.1&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;launchy&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;guard-rspec&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rspec&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 2.7.0&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rspec-rails&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 2.7.0&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;mongoid-rspec&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.4.4&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;spork&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 0.8.5&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;cucumber-rails&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.2.0&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;capybara&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="s1"&gt;&amp;#39;~&amp;gt; 1.1.1&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;email_spec&amp;#39;&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;simplecov&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="ss"&gt;:require&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rb-fsevent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="ss"&gt;:require&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;growl_notify&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;In this gemfile, I add two gems 'machinist_mongo and 'mongoid-rspec' because of I'm using Mongoid in my project, if you are using activerecord, just remove these two gems.&lt;/p&gt;

&lt;h4&gt;Installation&lt;/h4&gt;

&lt;p&gt;Just Run &lt;code&gt;bundle&lt;/code&gt; to install all the gems listed in gemfile&lt;/p&gt;

&lt;p&gt;RSpec works great with other assistant plugins as I listed above, I will introduce you one by one.&lt;/p&gt;

&lt;hr /&gt;

&lt;h4&gt;RSpec&lt;/h4&gt;

&lt;p&gt;Someone would say that unit testing framework is good enough, but what I would say is that RSpec is a Domain Specific Language for describing the expected behaviour of a system with executable examples.&lt;/p&gt;

&lt;h4&gt;Configuration&lt;/h4&gt;

&lt;p&gt;Initialize Rspec&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rails g rspec:install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It will generate files and directories as below&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;create  .rspec
create  spec
create  spec/spec_helper.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let's modify &lt;code&gt;spec_helper.rb&lt;/code&gt; to extend some awesome tools&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;simplecov&amp;#39;&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;spork&amp;#39;&lt;/span&gt;
    &lt;span class="no"&gt;SimpleCov&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rails&amp;#39;&lt;/span&gt;

    &lt;span class="c1"&gt;# This file is copied to spec/ when you run &amp;#39;rails generate rspec:install&amp;#39;&lt;/span&gt;
    &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RAILS_ENV&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rails/mongoid&amp;#39;&lt;/span&gt;
    &lt;span class="no"&gt;Spork&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trap_class_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:load_models&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;../../config/environment&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rspec/rails&amp;#39;&lt;/span&gt;

    &lt;span class="c1"&gt;# Requires supporting ruby files with custom matchers and macros, etc,&lt;/span&gt;
    &lt;span class="c1"&gt;# in spec/support/ and its subdirectories.&lt;/span&gt;
    &lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;spec/support/**/*.rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mock_with&lt;/span&gt; &lt;span class="ss"&gt;:rspec&lt;/span&gt;
      &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Matchers&lt;/span&gt;

      &lt;span class="no"&gt;DatabaseCleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:truncation&lt;/span&gt;

      &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="no"&gt;DatabaseCleaner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clean&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Bye the way, I would like to suggest you change your rails generator in &lt;code&gt;config/application.rb&lt;/code&gt;, add the following code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generators&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orm&lt;/span&gt;                 &lt;span class="ss"&gt;:mongoid&lt;/span&gt;
      &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;template_engine&lt;/span&gt;     &lt;span class="ss"&gt;:haml&lt;/span&gt;
      &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_framework&lt;/span&gt;      &lt;span class="ss"&gt;:rspec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:fixture&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:views&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fixture_replacement&lt;/span&gt; &lt;span class="ss"&gt;:machinist&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;hr /&gt;

&lt;h4&gt;Guard&lt;/h4&gt;

&lt;p&gt;Guard watches files and runs a command after a file is modified. This allows you to automatically run tests in the background, restart your development server, reload the browser, and more.&lt;/p&gt;

&lt;h5&gt;Configuration&lt;/h5&gt;

&lt;p&gt;After you run &lt;code&gt;bundle&lt;/code&gt; to install everything and, once that's done, run &lt;code&gt;guard init&lt;/code&gt; rspec to set up Guard&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ guard init
Writing new Guardfile to (here is your path)
rspec guard added to Guardfile, feel free to edit it
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It will generate a Guardfile in your rails root directory, make it like:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# A sample Guardfile&lt;/span&gt;
    &lt;span class="c1"&gt;# More info at https://github.com/guard/guard#readme&lt;/span&gt;

    &lt;span class="n"&gt;guard&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rspec&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:version&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;%r{^spec/.+_spec\.rb$}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;%r{^lib/(.+)\.rb$}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/lib/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_spec.rb&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;spec/spec_helper.rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;# Rails example&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;%r{^spec/.+_spec\.rb$}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;%r{^app/(.+)\.rb$}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_spec.rb&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;%r{^lib/(.+)\.rb$}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/lib/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_spec.rb&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;%r{^app/controllers/(.+)_(controller)\.rb$}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;spec/routing/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_routing_spec.rb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_spec.rb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/acceptance/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_spec.rb&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;%r{^spec/support/(.+)\.rb$}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;spec/spec_helper.rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;config/routes.rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/routing&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;app/controllers/application_controller.rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/controllers&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="c1"&gt;# Capybara request specs&lt;/span&gt;
      &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;%r{^app/views/(.+)/.*\.(erb|haml)$}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;spec/requests/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_spec.rb&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Guard also has support for Growl notifications and these can be enabled by installing the growl gem, You can find &lt;code&gt;rb-fsevent&lt;/code&gt; and &lt;code&gt;growl_notify&lt;/code&gt; as I listed in Gemfile, but it only works via Mac OSX, remove these if you are using linux.&lt;/p&gt;

&lt;p&gt;We can now run the &lt;code&gt;guard&lt;/code&gt; command to start up the Guard server.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ guard
Guard is now watching at '/Users/shenjerry/Workspace/demo'
Guard::RSpec is running, with RSpec 2!
Running all specs
...

Finished in 1.02 seconds
3 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we make a breaking change to our code, for example remove a method in your user model, Guard will run immediately and we’ll see the broken test clearly.&lt;/p&gt;

&lt;hr /&gt;

&lt;h4&gt;Machinist&lt;/h4&gt;

&lt;p&gt;Machinist is an awesome plugin which make it easy to create objects for use in tests, It generates data for the attributes you don't care about, and constructs any necessary associated objects, leaving you to specify only the fields you care about in your test.&lt;/p&gt;

&lt;h5&gt;Configuration&lt;/h5&gt;

&lt;pre&gt;&lt;code&gt;$ rails g machinist:install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It will generate &lt;code&gt;blueprint.rb&lt;/code&gt; file in your &lt;code&gt;spec/support&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Here is a example to define a blueprint:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;machinist/mongoid&amp;#39;&lt;/span&gt;

    &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;email&lt;/span&gt;     &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Faker&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Internet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;username&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;username_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;sn&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;password&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;password&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;password_confirmation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If you want to create a user in your console, you need require the blueprints first&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; require Rails.root.join('spec', 'support/blueprints')
&amp;gt;&amp;gt; User.make!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can find this user in database.&lt;/p&gt;

&lt;p&gt;Another case that you want to define a admin blueprint as the same user model, if you supposed to add a whole blueprint again, that's ugly.
Here is the simple way to handle this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;machinist/mongoid&amp;#39;&lt;/span&gt;

    &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;is_admin&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You can use &lt;code&gt;User.make!(:admin)&lt;/code&gt; to create a admin.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; require Rails.root.join('spec', 'support/blueprints')
&amp;gt;&amp;gt; User.make!(:admin)
&lt;/code&gt;&lt;/pre&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/11/28/getting-started-with-rspec/</feedburner:origLink></entry>
 
 <entry>
   <title>Supporting Dynamic Fields Form for Mongoid</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/TBbqWUEqjzc/" />
   <updated>2011-11-20T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/11/20/supporting-dynamic-fields-form-for-mongoid</id>
   <content type="html">&lt;p&gt;Mongoid currently supports the dynamic fields configuration option, which provided in the mongoid.yml,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;allow_dynamic_fields: true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When attributes are not defined as fields but added to an object, they will get fields added for them dynamically and will get persisted. If set to false an error will get raised when attempting to set a value that has no field defined.&lt;/p&gt;

&lt;p&gt;But there is a problem with a dynamic fields form, you will get raised when attempting to add a undefined atribute in your form, so question comes, how to enable form to support dynamic fields that could be added to an object? The only thing you should do is that override the &lt;code&gt;method_missing&lt;/code&gt; method in mongoid module.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Mongoid&lt;/span&gt; 
      &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Attributes&lt;/span&gt;
        &lt;span class="n"&gt;alias_method&lt;/span&gt; &lt;span class="ss"&gt;:old_method_missing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:method_missing&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;old_method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;rescue&lt;/span&gt;
          &lt;span class="kp"&gt;nil&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You can directly put this file in &lt;code&gt;config/initializer&lt;/code&gt; directory, or &lt;code&gt;lib&lt;/code&gt; and require this file, whatever you like.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/11/20/supporting-dynamic-fields-form-for-mongoid/</feedburner:origLink></entry>
 
 <entry>
   <title>Customize the Redirect for Devise</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/WW7TglPQVPg/" />
   <updated>2011-09-25T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/09/25/customize-the-redirect-for-devise</id>
   <content type="html">&lt;p&gt;Devise has many default redirect, it depends on what you'v done with Devise.&lt;/p&gt;

&lt;p&gt;Normally, after a user signed in, they are redirected to the root path.
But we should have Devise redirect to a custom route after signed in, such as a administrator.&lt;/p&gt;

&lt;p&gt;If you are using the default routes with Devise, add the override methods in your &lt;code&gt;ApplicationController&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;

      &lt;span class="kp"&gt;protected&lt;/span&gt;

        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;after_update_path_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_admin?&lt;/span&gt;
            &lt;span class="n"&gt;admin_root_path&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="k"&gt;super&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;That's it, it very easy to customize your routes, we have other routes could be customized.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;after_sign_out_path_for(resource)&lt;/li&gt;
&lt;li&gt;after_update_path_for(resource)&lt;/li&gt;
&lt;li&gt;sign_out_and_redirect(resource)&lt;/li&gt;
&lt;li&gt;after_resending_confirmation_instructions_path_for(resource_name)&lt;/li&gt;
&lt;li&gt;after_confirmation_path_for(resource_name, resource)&lt;/li&gt;
&lt;li&gt;after_omniauth_failure_path_for(resource_name)&lt;/li&gt;
&lt;li&gt;after_sending_reset_password_instructions_path_for(resource_name)&lt;/li&gt;
&lt;/ul&gt;

</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/09/25/customize-the-redirect-for-devise/</feedburner:origLink></entry>
 
 <entry>
   <title>Allow Users to Login with Username or Email Using Devise</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/t0x7Ey0n3gw/" />
   <updated>2011-09-20T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/09/20/allow-users-to-login-with-username-or-email-using-devise</id>
   <content type="html">&lt;p&gt;Devise is a flexible authentication solution for Rails based on Warden,
I love it because it's very simple to use and easy to extend or override. Many people would say that
It's too huge to include all the devise's modules, but what I would say is that, take it easy, agile is the most important, and it's not so huge because of most of the modules are necessary for such a simple project.&lt;/p&gt;

&lt;p&gt;Many websites are both enabled username and email to sign in, It will be very friendly to the users,
people will unhappy that every time they must type such a long email address. So Let me show you
how to allow users to login with username or email using Devise.&lt;/p&gt;

&lt;p&gt;First of all, you must have a column named 'username' in your users table.&lt;/p&gt;

&lt;p&gt;Then we can start, you should modify the User model and add username to attr_accessible.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;To support both username and email, you should create a login virtual attribute in Users and set the accessible&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# Virtual attribute for authenticating by either username or email&lt;/span&gt;
    &lt;span class="c1"&gt;# This is in addition to a real persisted field like &amp;#39;username&amp;#39;&lt;/span&gt;
    &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:login&lt;/span&gt;
    &lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:login&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;As default, Devise use &lt;code&gt;:email&lt;/code&gt; for authentication in the authentication_keys, so you should tell Devise to use
&lt;code&gt;:login&lt;/code&gt; in the authentication_keys, modify &lt;code&gt;config/initializers/devise.rb&lt;/code&gt; to have:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authentication_keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:login&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You should overwrite Devise’s &lt;code&gt;find_for_database_authentication&lt;/code&gt; method in user model&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# This is for ActiveRecord&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_for_database_authentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;warden_conditions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;conditions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;warden_conditions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dup&lt;/span&gt;
       &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;lower(username) = :value OR lower(email) = :value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;downcase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
     
     &lt;span class="c1"&gt;# This is for Mongoid:&lt;/span&gt;
     &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;
     
     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_for_database_authentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;any_of&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Note: This code for Mongoid does some small things differently then the ActiveRecord code above. Would be great if someone could port the complete functionality of the ActiveRecord code over to Mongoid [basically you need to port the ‘where(conditions)’]. It is not required but will allow greater flexibility.&lt;/p&gt;

&lt;p&gt;After these settings, make sure you have the Devise views in your project so that you can update &lt;code&gt;devise/sessions/new&lt;/code&gt; view.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;#  devise/sessions/new.html.erb&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= f.label :email %&amp;gt;&amp;lt;br /&amp;gt;&lt;/span&gt;
&lt;span class="sx"&gt;    -  &amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email_field&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= f.label :login %&amp;gt;&amp;lt;br /&amp;gt;&lt;/span&gt;
&lt;span class="sx"&gt;    +  &amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text_field&lt;/span&gt; &lt;span class="ss"&gt;:login&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Add i18n translation for login field&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;activerecord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
            &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Username or email&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Yeah, you have done with the configuration to allow user sign in with username or email address, now there is another problem, you also need to allow users to recover their password using either username or email address, right? Let's do it.&lt;/p&gt;

&lt;p&gt;Devise set the default reset password keys to &lt;code&gt;:email&lt;/code&gt;, so you have to tell Devise to use &lt;code&gt;:loign&lt;/code&gt;
in the &lt;code&gt;reset_password_keys&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    
    &lt;span class="c1"&gt;# config/initializers/devise.rb&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reset_password_keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:login&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Devises's finder methods in user model should be overwritten to support both username and email address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is for ActiveRecord&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="kp"&gt;protected&lt;/span&gt;

     &lt;span class="c1"&gt;# Attempt to find a user by it&amp;#39;s email. If a record is found, send new&lt;/span&gt;
     &lt;span class="c1"&gt;# password instructions to it. If not user is found, returns a new user&lt;/span&gt;
     &lt;span class="c1"&gt;# with an email not found error.&lt;/span&gt;
     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_reset_password_instructions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
       &lt;span class="n"&gt;recoverable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_recoverable_or_initialize_with_errors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reset_password_keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:not_found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;recoverable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_reset_password_instructions&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;recoverable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;persisted?&lt;/span&gt;
       &lt;span class="n"&gt;recoverable&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt; 

     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_recoverable_or_initialize_with_errors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required_attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="ss"&gt;:invalid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;case_insensitive_keys&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:downcase!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

       &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;required_attributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete_if&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blank?&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;required_attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="k"&gt;else&lt;/span&gt;  
           &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;
         &lt;span class="k"&gt;end&lt;/span&gt;  
       &lt;span class="k"&gt;end&lt;/span&gt;  

       &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;
         &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;new&lt;/span&gt;

         &lt;span class="n"&gt;required_attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
           &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;present?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:blank&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="k"&gt;end&lt;/span&gt;  
       &lt;span class="k"&gt;end&lt;/span&gt;  
       &lt;span class="n"&gt;record&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;

     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;username = :value OR email = :value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;These two are all for Mongoid&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="c1"&gt;# as finder&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_a&lt;/span&gt;
      &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_a&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
      &lt;span class="n"&gt;found&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# This can be optimized using a custom javascript function&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;function() {return this.username == &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39; || this.email == &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Don't forget to update your view and enjoy&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/09/20/allow-users-to-login-with-username-or-email-using-devise/</feedburner:origLink></entry>
 
 <entry>
   <title>Setting up PPTP VPN on Linode VPS</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/GlBZm-VPlR4/" />
   <updated>2011-08-10T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/08/10/setting-up-pptp-vpn-on-linode-vps</id>
   <content type="html">&lt;p&gt;&lt;a href="http://www.linode.com"&gt;Linode&lt;/a&gt; is a VPS hosting company built upon one simple premise: provide the best possible tools and services to those that what they need.&lt;/p&gt;

&lt;p&gt;I have a VPS on Linode, my blog runs on it, you can do any thing you want to do. For example we need to set up a PPTP VPN, it was based on Ubuntu Server 11.10 64bit.&lt;/p&gt;

&lt;p&gt;Fir of all, you should update your sources.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo apt-get update
$ sudo apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we can start to install VPN server, It's very easy to be set up with PPTP which is a kind of VPN Protocol.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo apt-get install pptpd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The only thing left to do is that we should add some configurations for pptpd.&lt;/p&gt;

&lt;p&gt;Modify &lt;code&gt;/etc/pptpd.conf&lt;/code&gt;, find 'localip' and 'remoteip' and replace with&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;localip 192.168.13.1
remoteip 192.168.13.50-100
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After add the ip scope, we can continue adding users VPN with modifying &lt;code&gt;/etc/ppp/chap-secrets&lt;/code&gt;, for example&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jerry pptpd 123456 *
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;BTW, here 'jerry' is your username, '123456' is your password&lt;/p&gt;

&lt;p&gt;Well, It's better to set a DNS to make sure pptpd can resove domains successfully when connected to VPN. You can modify &lt;code&gt;/etc/ppp/options&lt;/code&gt;, try to find &lt;code&gt;ms-dns&lt;/code&gt; and replace with Google's public DNS&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ms-dns 8.8.8.8
ms-dns 8.8.4.4
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then modify &lt;code&gt;/etc/sysctl.conf&lt;/code&gt;, try to find &lt;code&gt;net.ipv4.ip_forward=1&lt;/code&gt; and enable it.&lt;/p&gt;

&lt;p&gt;How to make the settings work? try to run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo sysctl -p
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;you also should restart pptpd's server&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo /etc/init.d/pptpd restart
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, we should transmit ips witl iptable&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo /sbin/iptables -t nat -A POSTROUTING -s 192.168.13.0/24 -o eth0 -j MASQUERADE
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But there is a problem here, when you restart your server, the transmitting will disappear, so we can add it into bootup script. Switch to your root user, create &lt;code&gt;transmition&lt;/code&gt; in &lt;code&gt;/etc/init.d/&lt;/code&gt; directory, and add the following script&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/sbin/iptables -t nat -A POSTROUTING -s 192.168.13.0/24 -o eth0 -j MASQUERADE
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You also have to make &lt;code&gt;transmition&lt;/code&gt; executable, using&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ chmod +x transmition
$ update-rc.d transmition defaults 
&lt;/code&gt;&lt;/pre&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/08/10/setting-up-pptp-vpn-on-linode-vps/</feedburner:origLink></entry>
 
 <entry>
   <title>Setting a Capisrano variable to Limit Releases</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/Q2kd_MrA03s/" />
   <updated>2011-06-10T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/06/10/setting-a-capistrano-variable-to-limit-releases</id>
   <content type="html">&lt;p&gt;Capistrano is a awesome tool to deploy your projects, Usually when using capistrano, I will go and manually delete old releases from a deployed application long time before. I understand that you can run &lt;code&gt;cap deploy:cleanup&lt;/code&gt; but that still leaves 5 releases. But what I want is just keep 3 releases or even less, It's very simple to cleanup old releases to just 3 previous deploy with a capistrano variable, add it to your deploy script.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;    &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;:keep_releases&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;deploy:restart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;deploy:cleanup&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Also there is option 2 to set the the capistrano variable from the command line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cap deploy:cleanup -s keep_releases=3
&lt;/code&gt;&lt;/pre&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/06/10/setting-a-capistrano-variable-to-limit-releases/</feedburner:origLink></entry>
 
 <entry>
   <title>Curl Problem when Installing Nginx Using Passenger Module</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/FACo9a2sVI0/" />
   <updated>2011-05-03T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2011/05/03/curl-problem-when-installing-nginx-using-passenger-module</id>
   <content type="html">&lt;p&gt;I often got this kind of problem when installing nginx using passenger module,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Checking for required software...

 * GNU C++ compiler... found at /usr/bin/g++
 * The 'make' tool... found at /usr/bin/make
 * A download tool like 'wget' or 'curl'... found at /usr/bin/wget
 * Ruby development headers... found
 * OpenSSL support for Ruby... found
 * RubyGems... found
 * Rake... found at /home/jerry/.rvm/wrappers/ruby-1.9.3-p0/rake
 * rack... found
 * Curl development headers with SSL support... not found
 * OpenSSL development headers... found
 * Zlib development headers... found

Some required software is not installed.
But don't worry, this installer will tell you how to install them.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yes, that's easy to resolve, your system is lack of a package named &lt;code&gt;libcurl4-openssl-dev&lt;/code&gt;,
You can install it with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo apt-get install libcurl4-openssl-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, run your &lt;code&gt;passenger-install-nginx-module&lt;/code&gt;, it will pass all the required packages.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2011/05/03/curl-problem-when-installing-nginx-using-passenger-module/</feedburner:origLink></entry>
 
 <entry>
   <title>Set up Git Server on Ubuntu Server</title>
   <link href="http://feedproxy.google.com/~r/JerryShen/~3/s31ShfnLRo0/" />
   <updated>2010-06-12T00:00:00+00:00</updated>
   <id>http://www.hansay.com/2010/06/12/set-up-git-server-on-ubuntu-server</id>
   <content type="html">&lt;p&gt;Git是一个开源的分布式版本控制系统, 用以有效、高速的处理从很小到非常大的项目版本管理.&lt;/p&gt;

&lt;p&gt;下面来介绍如何在安装ubuntu server系统的服务器上管理你的项目, 以 &lt;a href="http://www.llinode.com"&gt;linode VPS&lt;/a&gt; 为例.&lt;/p&gt;

&lt;p&gt;安装git-core和gitosis&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo apt-get install git-core gitosis
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;线确认你本地机器中是否已经生成过public key, 查看 &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt;, 如果还没有创建你的public key, 就需要通过ssh-keygen来生成:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ssh-keygen
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;执行以上命令后会在 &lt;code&gt;.ssh&lt;/code&gt; 目录下生成 &lt;code&gt;id_rsa&lt;/code&gt; 和 &lt;code&gt;id_rsa.pub&lt;/code&gt; 两个文件,&lt;/p&gt;

&lt;p&gt;当然如果你本地机器中如果已经有了public key, 就不需要再生成一次了, 接下来要做的就是在服务器上进行git-server的配置了, 先把你本地的public key scp到服务器的 &lt;code&gt;/tmp&lt;/code&gt; 目录下:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ scp ~/.ssh/id_rsa.pub your_username_here@your_server_ip_here:/tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;用刚scp上来的public key作为管理者来初始化gitosis:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo -H -u gitosis gitosis-init &amp;lt; /tmp/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;完成后，你应该会看到以下信息:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Initialized empty Git repository in /srv/gitosis/repositories/gitosis-admin.git/
Reinitialized existing Git repository in /srv/gitosis/repositories/gitosis-admin.git/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;到这里, 刚才的public key已经没有用了, 可以删除&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rm /tmp/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;gitosis的配置已经完成, 接下来就可以把gitosis的管理项目clone到本地进行项目的管理了，前提是在在服务器上必须有你的证书:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone gitosis@your_server_ip_here:gitosis-admin.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;取到gitosis-admin这个管理项目后, 我们就可以任意增加项目成员和添加新的项目了, 可以通过编辑配置文件来完成:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd gitosis-admin
vim gitosis.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;添加一个名为foo的项目:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[gitosis]

[group gitosis-admin]
writable = gitosis-admin
members = key

[group foo]
writable = foo
members = key
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;保存该文件，然后提交改动:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git commit -a -m "add a new project"
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来新建一个项目,来测试一下配置是否正确:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rails new foo
cd foo
git init
git add .
git commit -a -m "first commit"
git remote add origin gitosis@your_server_ip_here:foo.git
git push origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;项目提交成功。foo这个项目已经可以协作开发了.&lt;/p&gt;
</content>
 <feedburner:origLink>http://www.huangzhimin.com/2010/06/12/set-up-git-server-on-ubuntu-server/</feedburner:origLink></entry>
 

</feed>

