<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Raymond Law: Tag ruby</title>
    <link>http://blog.rayvinly.com/articles/tag/ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Sanitize your output in Ruby on Rails</title>
      <description>&lt;p&gt;We all know about the holy h() method that escapes your output when you do &amp;lt;&lt;span&gt;=h blah %&amp;gt;.  But how many of us can claim we remember to use it where it&amp;#8217;s appropriate during development 100&lt;/span&gt; of the time?  Can you swear you&amp;#8217;ve never missed one?  Moreover, it&amp;#8217;s such a mental distraction to think logic and h() at the same time.  And when you take over a Rails project in the middle, how can you ensure the previous developers use h()?&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s the rescue.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://github.com/pelargir/safe_erb"&gt;safe_erb&lt;/a&gt; + &lt;a href="http://github.com/drnic/rails-footnotes"&gt;footnotes&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I don&amp;#8217;t think I need to explain more.  Just use it and you will find all those places where you should sanitize your output with h(), sanitize(), and untaint(), ...etc.&lt;/p&gt;</description>
      <pubDate>Thu, 30 Oct 2008 14:37:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:2139fb2c-3adc-4a1c-9de8-56bf527e1f9a</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/10/30/sanitize-your-output-in-ruby-on-rails</link>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>safe_erb</category>
      <category>footnotes</category>
      <category>sanitize</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/73</trackback:ping>
    </item>
    <item>
      <title>RailsRumble 2008</title>
      <description>&lt;p&gt;We just finished the &lt;a href="http://lyricistapp.com"&gt;Lyricist&lt;/a&gt; application for &lt;a href="http://railsrumble.com"&gt;RailsRumble 2008&lt;/a&gt; with 3 other &lt;a href="http://intridea.com"&gt;Intridea&lt;/a&gt; folks.  Here are some observations:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Keep the idea small and achievable&lt;/strong&gt; &amp;#8211; There are only 48 hours, so you can&amp;#8217;t build the next Google.  And there&amp;#8217;s pressure.  Try to keep your idea small and make sure you can accomplish it.  You have to deploy a finished product in order to have any chance of winning.  So stop day dreaming about cool extra features because you won&amp;#8217;t get that implemented.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Prior planning is the key&lt;/strong&gt; &amp;#8211; We barely had any because we had decided on the idea the day before the rumble began.  When the competition started, people don&amp;#8217;t know who&amp;#8217;s doing what and it was kinda a mess.  Fortunately we had a campfire room where all conversation happen, so we can kind of iron out the issues.  However, better preparation and team cohesiveness would have helped a great deal in communication.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Deploy early&lt;/strong&gt; &amp;#8211; I&amp;#8217;ve seen too many deployment problems came up before, so I took the initiative to make sure we could deploy as soon as the competition began.  It helped tremendously because we never had to worry about if we could deploy before time expired.  While you are fixing last minute bugs and the pressure, it would have been tough to set up a server and deploy flawlessly.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;A lot of scaffolding&lt;/strong&gt; &amp;#8211; I took full advantage of Rails scaffolding.  There&amp;#8217;s just no time to reinvent the wheels when all the restful model and controller methods are already available with just one command.  You use plugins and gems for the same reason, right?  So, don&amp;#8217;t be stupid.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Conflicts&lt;/strong&gt; &amp;#8211; The bigger your team, the more conflicts there would be when people check in and out.  We were writing a new application, so people were editing the same files.  Now, if you organize and assign work to people as in a regular project, conflicts don&amp;#8217;t usually happen and even if they do occur, it is trivial to resolve.  However, when you are rumbling, you will step on one another&amp;#8217;s toes.  I can guarantee you that.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Forget about writing tests&lt;/strong&gt; &amp;#8211; Look, I am in support of agile and test-driven development, with one exception.  That is, you are not participating in RailsRumble.  There&amp;#8217;s just no time for it.  If you are a good enough programmer, you can build a small application with no tests.  If you can&amp;#8217;t, I don&amp;#8217;t want to work with you.  Writing tests for a new application starting from scratch in just 48 hours is simple not feasible.  No bargain!&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;No ticketing system like Unfuddle and Lighthouse&lt;/strong&gt; &amp;#8211; One team member had tried to use Unfuddle to create tickets to get ourselves more organized.  While it was a sincere attempt, it simply didn&amp;#8217;t work.  There&amp;#8217;s no time to accept a ticket, create a new ticket, ...  We pretty much abandoned it soon after we started.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Nice to have a designer&lt;/strong&gt;: &amp;#8211; It is very nice if you have a designer on you team because it&amp;#8217;s hard to wear two hats in 48 hours.  Design work can draw your focus away from development.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Now that I&amp;#8217;ve given you my insights for next year&amp;#8217;s RailsRumble.  As a token of appreciation, please &lt;a href="http://railsrumble.com/teams/the-unstable-isotopes"&gt;vote for us&lt;/a&gt;!&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE 2008&lt;/span&gt;/10/20&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;One more thought on RailsRumble the day after:&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Numerous projects that I worked with before never deploy quickly, let alone in 48 hours.  I think it&amp;#8217;s refreshing and rewarding to have something built and deployed so quickly.  It is true that we have to cut many features in order to deploy a first version, but lesser is better than never.  I think many other projects can try to deploy early and often and just go through more iterations and get feedbacks from users and customers.  The whole application doesn&amp;#8217;t need to be finished.  Even if you only have login and logout, you can still deploy.  Add the next feature, deploy again.  That way, you aren&amp;#8217;t keeping the features to yourself.  You can get feedback from users to see what improvements they are looking for and may even lead you to implement the real features that they truly want.&lt;/p&gt;</description>
      <pubDate>Sun, 19 Oct 2008 19:40:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:71bf621b-35c6-4a75-ad14-562651eaf015</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/10/19/railsrumble-2008</link>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>railsrumble</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/71</trackback:ping>
    </item>
    <item>
      <title>Capistrano Deployment Recipes</title>
      <description>&lt;p&gt;&lt;a href="http://dealistic.com/"&gt;Dealistic&lt;/a&gt; was first deployed to &lt;a href="http://www.slicehost.com/"&gt;Slicehost&lt;/a&gt; when we were testing it on staging.  However, I only got the 256 slice and low memory is a big problem for Ruby and Mongrel.  We&amp;#8217;ve moved to &lt;a href="http://www.amazon.com/gp/browse.html?node=201590011"&gt;Amazon &lt;span class="caps"&gt;EC2&lt;/span&gt;&lt;/a&gt; when we launched.  It is running rock solid and we don&amp;#8217;t run out of memory again, at least for now :P&lt;/p&gt;


	&lt;p&gt;As a result of all these, I wrote two &lt;a href="http://www.capify.org/"&gt;Capistrano&lt;/a&gt; recipes for deployment, for both Slicehost and &lt;span class="caps"&gt;EC2&lt;/span&gt;.  We also use &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt; for version control.  I think these deployment recipes may be helpful to others.  So here they are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://blog.rayvinly.com/shared/deploy_slicehost.rb"&gt;deploy.rb for Slicehost&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://blog.rayvinly.com/shared/deploy_ec2.rb"&gt;deploy.rb for &lt;span class="caps"&gt;EC2&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;We wrote some custom Capistrano tasks to copy over configuration files, symlink plugins, start/stop &lt;a href="http://backgroundrb.rubyforge.org/"&gt;BackgrounDRb&lt;/a&gt;, and a custom maintenance page.  But these things are optional.  It should be simple to add/remove things as you see fit.&lt;/p&gt;</description>
      <pubDate>Mon, 04 Aug 2008 17:30:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:f24253c2-5880-49fb-8e78-8d74075c0cbb</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/08/04/capistrano-deployment-recipes</link>
      <category>Entrepreneurship</category>
      <category>Git</category>
      <category>Dealistic</category>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>dealistic</category>
      <category>slicehost</category>
      <category>amazon</category>
      <category>ec2</category>
      <category>capistrano</category>
      <category>github</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/69</trackback:ping>
    </item>
    <item>
      <title>Ruby Performance Benchmarking</title>
      <description>&lt;p&gt;Courtesy of &lt;a href="http://www.igvita.com/2008/07/08/6-optimization-tips-for-ruby-mri/"&gt;igvita.com&lt;/a&gt;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;benchmark&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="ident"&gt;n&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;1000000&lt;/span&gt;
&lt;span class="constant"&gt;Benchmark&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;bm&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;report&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;copy&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;;&lt;/span&gt; &lt;span class="ident"&gt;h&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{};&lt;/span&gt; &lt;span class="ident"&gt;h&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;h&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;merge&lt;/span&gt;&lt;span class="punct"&gt;({&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;});&lt;/span&gt; &lt;span class="keyword"&gt;end&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;

  &lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;report&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;no copy&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;;&lt;/span&gt; &lt;span class="ident"&gt;h&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{};&lt;/span&gt; &lt;span class="ident"&gt;h&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;merge!&lt;/span&gt;&lt;span class="punct"&gt;({&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;});&lt;/span&gt; &lt;span class="keyword"&gt;end&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;

  &lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;report&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;map(&amp;amp;:id)&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;h&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{}&lt;/span&gt;
      &lt;span class="ident"&gt;h&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;(&amp;amp;&lt;/span&gt;&lt;span class="symbol"&gt;:object_id&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;report&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;map { |i| i.id }&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;h&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{}&lt;/span&gt;
      &lt;span class="ident"&gt;h&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;e&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;e&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;object_id&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;In Rails script/console or Ruby 1.9:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="punct"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;load&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/Users/rlaw/Desktop/bm.rb&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
      &lt;span class="ident"&gt;user&lt;/span&gt;     &lt;span class="ident"&gt;system&lt;/span&gt;      &lt;span class="ident"&gt;total&lt;/span&gt;        &lt;span class="ident"&gt;real&lt;/span&gt;
&lt;span class="ident"&gt;copy&lt;/span&gt;  &lt;span class="number"&gt;4.000000&lt;/span&gt;   &lt;span class="number"&gt;0.020000&lt;/span&gt;   &lt;span class="number"&gt;4.020000&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;  &lt;span class="number"&gt;4.081549&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;no&lt;/span&gt; &lt;span class="ident"&gt;copy&lt;/span&gt;  &lt;span class="number"&gt;2.780000&lt;/span&gt;   &lt;span class="number"&gt;0.010000&lt;/span&gt;   &lt;span class="number"&gt;2.790000&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;  &lt;span class="number"&gt;2.818923&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;(&amp;amp;&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="number"&gt;10.880000&lt;/span&gt;   &lt;span class="number"&gt;0.040000&lt;/span&gt;  &lt;span class="number"&gt;10.920000&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="number"&gt;11.094024&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;  &lt;span class="number"&gt;2.060000&lt;/span&gt;   &lt;span class="number"&gt;0.020000&lt;/span&gt;   &lt;span class="number"&gt;2.080000&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;  &lt;span class="number"&gt;2.178544&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Wed, 09 Jul 2008 20:55:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:7f698a40-885f-41f0-9759-031a4833af89</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/07/09/ruby-performance-benchmarking</link>
      <category>Ruby on Rails</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>performance</category>
      <category>benchmark</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/66</trackback:ping>
    </item>
    <item>
      <title>Deploying your Rails applications with Phusion Passenger</title>
      <description>&lt;p&gt;There have been several methods to deploy an Ruby on Rails application.  Until recently, the most popular is to run Apache and proxy balance to multiple Mongrel instances that are running simultaneously.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.modrails.com/"&gt;Passenger&lt;/a&gt;, developed by &lt;a href="http://www.phusion.nl/about.html"&gt;Phusion&lt;/a&gt;, is the new kid entering the Rails deployment market.  We have been using the Apache &lt;span class="caps"&gt;PHP&lt;/span&gt; module for years and deploying a &lt;span class="caps"&gt;PHP&lt;/span&gt; applications is a snap.  This has not been possible with Rails until Passenger.  It is so easy too!  You can still use &lt;a href="http://capify.org/"&gt;Capistrano&lt;/a&gt; to automate deployment.  I will show you how I get it to work on Ubuntu.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;sudo gem install passenger
passenger-install-apache2-module&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Phusion just released &lt;a href="http://phusion-passenger.googlecode.com/files/passenger-1.9.0.gem"&gt;Passenger 2.0 &lt;span class="caps"&gt;RC 1&lt;/span&gt;&lt;/a&gt;.  You can download this version and do &lt;code&gt;gem install passenger-1.9.0.gem&lt;/code&gt; instead.  But I had an error compiling it on Mac &lt;span class="caps"&gt;OS X&lt;/span&gt; Leopard.  hongli pointed me to use the version from &lt;a href="http://github.com/FooBarWidget/passenger/tree/master"&gt;GitHub&lt;/a&gt; that has the fix and it works like a charm.  Thanks Phusion guys.&lt;/p&gt;


	&lt;p&gt;To get it from GitHub:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;git clone git://github.com/FooBarWidget/passenger.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I create a separate &lt;code&gt;/etc/apache2/mods-available/passenger.load&lt;/code&gt; and it contains the following:&lt;/p&gt;


	&lt;p&gt;For 1.0.5:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.5/ext/apache2/mod_passenger.so
RailsSpawnServer /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.5/bin/passenger-spawn-server
RailsRuby /usr/local/bin/ruby&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;For the GitHub version (Of course the path will look different depending on where your git clone is):&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;LoadModule passenger_module /home/rlaw/downloads/passenger/ext/apache2/mod_passenger.so
PassengerRoot /home/rlaw/downloads/passenger
PassengerRuby /usr/local/bin/ruby&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I then tell Apache to load the Passenger module:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;a2enmod passenger&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now, I create a virtual host configuration for one of my Rails app in &lt;code&gt;/etc/apache2/sites-available/dealistic&lt;/code&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;lt;VirtualHost *:80&amp;gt;
  ServerAdmin webmaster@dealistic.com
  ServerName dealistic.com

  DocumentRoot /home/deploy/apps/dealistic/current/public

  &amp;lt;Directory /home/deploy/apps/dealistic/current/public&amp;gt;
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
  &amp;lt;/Directory&amp;gt;

  LogLevel warn
  ErrorLog /var/log/apache2/dealistic/error.log
  CustomLog /var/log/apache2/dealistic/access.log combined
&amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I then restart Apache:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;sudo /etc/init.d/apache2 reload&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;When you need to restart your application because you have changed some code that Rails does not reload in production, just do:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;touch /home/deploy/apps/dealistic/current/tmp/restart.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I have not tried their &lt;a href="http://www.rubyenterpriseedition.com/"&gt;Ruby Enterprise Edition&lt;/a&gt; yet.  They claim substantial memory and speed improvement at &lt;a href="http://en.oreilly.com/rails2008/public/schedule/detail/4354"&gt;RailsConf 2008&lt;/a&gt;, so it will be interesting to see.&lt;/p&gt;</description>
      <pubDate>Tue, 24 Jun 2008 10:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:43311149-3ecb-4bad-b3bc-c7dceca4269b</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/06/24/deploying-your-rails-applications-with-phusion-passenger</link>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>deploy</category>
      <category>deployment</category>
      <category>apache</category>
      <category>passenger</category>
      <category>phusion</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/65</trackback:ping>
    </item>
    <item>
      <title>Badger Rails Plugin</title>
      <description>&lt;p&gt;&lt;em&gt;(I also posted about this plugin in the &lt;a href="http://intridea.com/2008/6/16/announcing-the-badger-rails-plugin"&gt;Intridea blog&lt;/a&gt; )&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://github.com/rayvinly/badger/tree/master"&gt;Badger&lt;/a&gt; (hosted at &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt;) is a simple Rails plugin that creates badges.  A site often allows its users to upload a profile image.  A profile image is just that, an image resized to fit in a predefined space to show up in the user&amp;#8217;s profile.&lt;/p&gt;


	&lt;p&gt;With Badger, you can have something prettier &amp;#8211; a badge that shows the user-uploaded image on top of another image that identifies the user as a part of the community.  We have company badges, security badges, so why not web badges to have your users show off his/her affection for your site?&lt;/p&gt;


	&lt;p&gt;Badger works by accepting cropping parameters of the overlay image in a hash (x1, y1, width, height), which is used to crop the overlay image.  It then resizes the cropped image to the size specified by composite_width and composite_height in badger.yml.  Finally, it places the resized image on top of the background image at location specified by composite_x and composite_y in badger.yml.  The resulting image is saved back to either the filesystem or Amazon S3, using attachment_fu.&lt;/p&gt;


	&lt;p&gt;Badger requires the attachment_fu plugin, ImageMagick, and MiniMagick.  Also, the JavaScript Image Cropper UI can be used to obtain the cropping parameters from the users.&lt;/p&gt;


	&lt;p&gt;For example:&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://img.skitch.com/20080415-s2twpkugcjfmpp27fqs42upi7.png" alt="" /&gt;
+
&lt;img src="http://img.skitch.com/20080415-xukti26i4q12bhr8tdxegadsbx.png" alt="" /&gt;
=
&lt;img src="http://img.skitch.com/20080415-g1k6y99fk5fnn4qti76xcyutp8.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Here I overlay &lt;span class="caps"&gt;RUBY&lt;/span&gt; on top of &lt;span class="caps"&gt;JAVA&lt;/span&gt; to produce &lt;span class="caps"&gt;I LOVE RUBY&lt;/span&gt;.&lt;/p&gt;</description>
      <pubDate>Mon, 23 Jun 2008 10:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:b89d8dd8-08ec-4f8a-8f86-684c535d8736</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/06/23/badger-rails-plugin</link>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>badger</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>plugin</category>
      <category>github</category>
      <category>intridea</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/58</trackback:ping>
    </item>
    <item>
      <title>Back from RailsConf 2008</title>
      <description>&lt;p&gt;Photos posted to my &lt;a href="http://flickr.com/photos/rayvinly/sets/72157605409054629/"&gt;flickr&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 04 Jun 2008 11:31:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:b02ad881-d337-46f2-a8a9-1e6d9ffddeec</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/06/04/back-from-railsconf-2008</link>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>railsconf</category>
      <category>railsconf2008</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/63</trackback:ping>
    </item>
    <item>
      <title>Attending RailsConf 2008</title>
      <description>&lt;p style="float:right"&gt;&lt;a href="http://conferences.oreilly.com/rails/"&gt;&lt;img src="http://conferences.oreillynet.com/banners/rails/promote/125x125.gif" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I will be attending the &lt;a href="http://railsconf.com"&gt;RailsConf&lt;/a&gt; from 5/29 to 6/1 in Portland with my colleagues from &lt;a href="http://intridea.com"&gt;Intridea&lt;/a&gt;.  It is going to be great to see the whole team there, and attend the different sessions.  I am really excited to meet other Rails enthusiasts and talk about projects we are working on.&lt;/p&gt;


	&lt;p&gt;We will be helping with the Community Project Code-Drive on 5/29 from 10am to 5pm.  Come check us out.&lt;/p&gt;


	&lt;p&gt;Josh Owens and Chris Selmer will also be presenting &lt;a href="http://en.oreilly.com/rails2008/public/schedule/detail/1935"&gt;  Building an app in 48 hours &amp;#8211; A Rails Rumble Case Study&lt;/a&gt; to talk about their fast developments in their participation of the Rails Rumble event.  Josh won first place with &lt;a href="http://tastyplanner.com/"&gt;Tasty Planner&lt;/a&gt; in the event!  Chris participated as a solo team on &lt;a href="http://www.yourpetrecords.com/"&gt;Your Pet Records&lt;/a&gt;.  Come attend their session to see how they developed an app in just 48 short hours!&lt;/p&gt;</description>
      <pubDate>Fri, 23 May 2008 16:29:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:b5694fa0-18f7-4e44-a7d1-ae7728dc9f6f</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/05/23/attending-railsconf-2008</link>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>web2.0</category>
      <category>railsconf</category>
      <category>portland</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/62</trackback:ping>
    </item>
    <item>
      <title>Tricky Git Submodule</title>
      <description>&lt;p&gt;I recently spent a good amount of time figuring out why the &lt;a href="http://www.mbleigh.com/plugins/acts-as-taggable-on-customizable-tagging-for-rails"&gt;acts_as_taggable_on&lt;/a&gt; plugin did not work for me.  I used Git&amp;#8217;s submodule to grab the code fom GitHub.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git submodule add git://github.com/mbleigh/acts-as-taggable-on.git vendor/plugin/acts-as-taggable-on&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;It seems logical to name my plugin directory with dashes since that&amp;#8217;s what the path suggests, right?  Wrong!  If you do that, it does not work because the plugin expects underscores.  This is probably due to the way Rails finds and loads the plugins, I guess.  Haven&amp;#8217;t had time to really dig deep into that&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Use this instead:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git submodule add git://github.com/mbleigh/acts-as-taggable-on.git vendor/plugin/acts_as_taggable_on&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I initially didn&amp;#8217;t pay attention to this because before Git, I just used:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; script/plugin install http://svn.intridea.com/svn/public/acts_as_taggable_on/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I did not have to explicitly tell where to put the plugin.  script/plugin is a Rails thing while Git is not.&lt;/p&gt;


	&lt;p&gt;Hopefully anyone who gets tripped up by this in the future will find out this post.&lt;/p&gt;</description>
      <pubDate>Tue, 29 Apr 2008 01:03:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:54d24e33-5043-4f89-a99a-18a5dc77bc62</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/04/29/tricky-git-submodule</link>
      <category>Git</category>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>git</category>
      <category>submodule</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>plugin</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/61</trackback:ping>
    </item>
    <item>
      <title>Using Git Branches and Stash</title>
      <description>&lt;p&gt;I recently started to learn and use Git for one of my projects.  Git encourages easy and cheap branching, here&amp;#8217;s what I do with Git branches and stash to switch between branches while working on different things.&lt;/p&gt;


	&lt;p&gt;Assume we want to develop yet another blog engine with Rails:&lt;/p&gt;


	&lt;p&gt;Create the application.  No surprise here!&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; rails -d mysql blog
&amp;gt; cd blog&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Initialize the Git repository.  This will create a .git/ directory in your project.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git init
Initialized empty Git repository in .git/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Add everything in your project directory for the next commit to Git.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git add .&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Lets see what will be commited.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use &amp;quot;git rm --cached &amp;lt;file&amp;gt;...&amp;quot; to unstage)
#
#    new file: README
#    new file: Rakefile
#    new file: app/controllers/application.rb
#    new file: app/helpers/application_helper.rb
#    new file: config/boot.rb
#    new file: config/database.yml
#    new file: config/environment.rb
#    new file: config/environments/development.rb
#    new file: config/environments/production.rb
#    new file: config/environments/test.rb
#    new file: config/initializers/inflections.rb
#    new file: config/initializers/mime_types.rb
#    new file: config/routes.rb
#    new file: doc/README_FOR_APP
#    new file: log/development.log
#    new file: log/production.log
#    new file: log/server.log
#    new file: log/test.log
#    new file: public/.htaccess
#    new file: public/404.html
#    new file: public/422.html
#    new file: public/500.html
#    new file: public/dispatch.cgi
#    new file: public/dispatch.fcgi
#    new file: public/dispatch.rb
#    new file: public/favicon.ico
#    new file: public/images/rails.png
#    new file: public/index.html
#    new file: public/javascripts/application.js
#    new file: public/javascripts/controls.js
#    new file: public/javascripts/dragdrop.js
#    new file: public/javascripts/effects.js
#    new file: public/javascripts/prototype.js
#    new file: public/robots.txt
#    new file: script/about
#    new file: script/console
#    new file: script/destroy
#    new file: script/generate
#    new file: script/performance/benchmarker
#    new file: script/performance/profiler
#    new file: script/performance/request
#    new file: script/plugin
#    new file: script/process/inspector
#    new file: script/process/reaper
#    new file: script/process/spawner
#    new file: script/runner
#    new file: script/server
#    new file: test/test_helper.rb
#&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Lets do our first commit.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git commit -m 'Initial commit'
Created initial commit aa5e7a0: Initial commit
 43 files changed, 8362 insertions(+), 0 deletions(-)
 create mode 100644 README
 create mode 100644 Rakefile
 create mode 100644 app/controllers/application.rb
 create mode 100644 app/helpers/application_helper.rb
 create mode 100644 config/boot.rb
 create mode 100644 config/database.yml
 create mode 100644 config/environment.rb
 create mode 100644 config/environments/development.rb
 create mode 100644 config/environments/production.rb
 create mode 100644 config/environments/test.rb
 create mode 100644 config/initializers/inflections.rb
 create mode 100644 config/initializers/mime_types.rb
 create mode 100644 config/routes.rb
 create mode 100644 doc/README_FOR_APP
 create mode 100644 log/development.log
 create mode 100644 log/production.log
 create mode 100644 log/server.log
 create mode 100644 log/test.log
 create mode 100644 public/.htaccess
 create mode 100644 public/404.html
 create mode 100644 public/422.html
 create mode 100644 public/500.html
 create mode 100755 public/dispatch.cgi
 create mode 100755 public/dispatch.fcgi
 create mode 100755 public/dispatch.rb
 create mode 100644 public/favicon.ico
 create mode 100644 public/images/rails.png
 create mode 100644 public/index.html
 create mode 100644 public/javascripts/application.js
 create mode 100644 public/javascripts/controls.js
 create mode 100644 public/javascripts/dragdrop.js
 create mode 100644 public/javascripts/effects.js
 create mode 100644 public/javascripts/prototype.js
 create mode 100644 public/robots.txt
 create mode 100755 script/about
 create mode 100755 script/console
 create mode 100755 script/destroy
 create mode 100755 script/generate
 create mode 100755 script/performance/benchmarker
 create mode 100755 script/performance/profiler
 create mode 100755 script/performance/request
 create mode 100755 script/plugin
 create mode 100755 script/process/inspector
 create mode 100755 script/process/reaper
 create mode 100755 script/process/spawner
 create mode 100755 script/runner
 create mode 100755 script/server
 create mode 100644 test/test_helper.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Our project is in the Git repository now.  Lets see what branches it currently has.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git branch
* master&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;It only has one branch called master, which is the default branch created by Gik, a.k.a. Subversion&amp;#8217;s trunk.&lt;/p&gt;


	&lt;p&gt;Our blog is going to have posts and comments.  So we probably should create the Post and Comment resources.  Before we do that, lets do some forward thinking.  While working on the blog, we likely will be working with posts and comments at the same time.  It will be confusing and unnessarily consume our brain cells if we were to remember which files and changes are for fixing a bug in posts or comments.  It may be a good idea to create separate branches for working on posts and comments.  So lets do that first.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git branch posts
&amp;gt; git branch comments&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Use gitk to show a visual picture of where we are.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://img.skitch.com/20080427-57197wsbi5mrqy76xa53hggid.png" alt="" /&gt;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git branch
  comments
* master
  posts&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;So we have three branches: master, posts, and comments.  We are currently working in the master branch.  Great!&lt;/p&gt;


	&lt;p&gt;Lets switch to the posts branch.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git checkout posts
Switched to branch &amp;quot;posts&amp;quot;
&amp;gt; git branch
  comments
  master
* posts&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;We are now ready to generate our resources&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; script/generate resource post title:string body:text published:boolean&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;And add and commit these new files to our Git repository.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git add .
&amp;gt; git commit -m 'Created Post resource'
Created commit 1ec37dc: Created Post resource
 8 files changed, 50 insertions(+), 0 deletions(-)
 create mode 100644 app/controllers/posts_controller.rb
 create mode 100644 app/helpers/posts_helper.rb
 create mode 100644 app/models/post.rb
 create mode 100644 db/migrate/001_create_posts.rb
 create mode 100644 test/fixtures/posts.yml
 create mode 100644 test/functional/posts_controller_test.rb
 create mode 100644 test/unit/post_test.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;If we switch back to our master branch, we find that the Post resource we just created is gone!  Don&amp;#8217;t worry.  They are in the posts branch but not in the master branch.  Gitk shows this.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://img.skitch.com/20080427-qipj3atwg6r5kee9chj1g69we7.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Lets switch to the comments branch and create the Comment resource.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git checkout comments
Switched to branch &amp;quot;comments&amp;quot;
&amp;gt; script/generate resource comment name:string blog:string body:text
&amp;gt; git add .
&amp;gt; git commit -m 'Created Comment resource'
Created commit 7f110d3: Created Comment resource
 8 files changed, 50 insertions(+), 0 deletions(-)
 create mode 100644 app/controllers/comments_controller.rb
 create mode 100644 app/helpers/comments_helper.rb
 create mode 100644 app/models/comment.rb
 create mode 100644 db/migrate/001_create_comments.rb
 create mode 100644 test/fixtures/comments.yml
 create mode 100644 test/functional/comments_controller_test.rb
 create mode 100644 test/unit/comment_test.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now we created a Post resource in the posts branch and a Comment resource in the comments branch.  We want to merge them back together to the master branch.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git checkout master
Switched to branch &amp;quot;master&amp;quot;
&amp;gt; git merge posts
Updating c680d0c..1ec37dc
Fast forward
 app/controllers/posts_controller.rb      |    2 ++
 app/helpers/posts_helper.rb              |    2 ++
 app/models/post.rb                       |    2 ++
 config/routes.rb                         |    2 ++
 db/migrate/001_create_posts.rb           |   15 +++++++++++++++
 test/fixtures/posts.yml                  |   11 +++++++++++
 test/functional/posts_controller_test.rb |    8 ++++++++
 test/unit/post_test.rb                   |    8 ++++++++
 8 files changed, 50 insertions(+), 0 deletions(-)
 create mode 100644 app/controllers/posts_controller.rb
 create mode 100644 app/helpers/posts_helper.rb
 create mode 100644 app/models/post.rb
 create mode 100644 db/migrate/001_create_posts.rb
 create mode 100644 test/fixtures/posts.yml
 create mode 100644 test/functional/posts_controller_test.rb
 create mode 100644 test/unit/post_test.rb
&amp;gt; git merge comments
Auto-merged config/routes.rb
CONFLICT (content): Merge conflict in config/routes.rb
Automatic merge failed; fix conflicts and then commit the result.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Oops!  There seems to be a config in config/routes.rb.  Lets see what is in that file.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;ActionController&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Routing&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Routes&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;draw&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;HEAD&lt;/span&gt;&lt;span class="symbol"&gt;:config&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;routes&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;rb&lt;/span&gt;
  &lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;resources&lt;/span&gt; &lt;span class="symbol"&gt;:posts&lt;/span&gt;
&lt;span class="punct"&gt;=======&lt;/span&gt;
  &lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;resources&lt;/span&gt; &lt;span class="symbol"&gt;:comments&lt;/span&gt;
&lt;span class="punct"&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;comments&lt;/span&gt;&lt;span class="symbol"&gt;:config&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;routes&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;rb&lt;/span&gt;

  &lt;span class="comment"&gt;# The priority is based upon order of creation: first created -&amp;gt; highest priority.&lt;/span&gt;

  &lt;span class="comment"&gt;# Sample of regular route:&lt;/span&gt;
  &lt;span class="comment"&gt;#   map.connect 'products/:id', :controller =&amp;gt; 'catalog', :action =&amp;gt; 'view'&lt;/span&gt;
  &lt;span class="comment"&gt;# Keep in mind you can assign values other than :controller and :action&lt;/span&gt;

  &lt;span class="comment"&gt;# Sample of named route:&lt;/span&gt;
  &lt;span class="comment"&gt;#   map.purchase 'products/:id/purchase', :controller =&amp;gt; 'catalog', :action =&amp;gt; 'purchase'&lt;/span&gt;
  &lt;span class="comment"&gt;# This route can be invoked with purchase_url(:id =&amp;gt; product.id)&lt;/span&gt;

  &lt;span class="comment"&gt;# Sample resource route (maps HTTP verbs to controller actions automatically):&lt;/span&gt;
  &lt;span class="comment"&gt;#   map.resources :products&lt;/span&gt;

  &lt;span class="comment"&gt;# Sample resource route with options:&lt;/span&gt;
  &lt;span class="comment"&gt;#   map.resources :products, :member =&amp;gt; { :short =&amp;gt; :get, :toggle =&amp;gt; :post }, :collection =&amp;gt; { :sold =&amp;gt; :get }&lt;/span&gt;

  &lt;span class="comment"&gt;# Sample resource route with sub-resources:&lt;/span&gt;
  &lt;span class="comment"&gt;#   map.resources :products, :has_many =&amp;gt; [ :comments, :sales ], :has_one =&amp;gt; :seller&lt;/span&gt;

  &lt;span class="comment"&gt;# Sample resource route within a namespace:&lt;/span&gt;
  &lt;span class="comment"&gt;#   map.namespace :admin do |admin|&lt;/span&gt;
  &lt;span class="comment"&gt;#     # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)&lt;/span&gt;
  &lt;span class="comment"&gt;#     admin.resources :products&lt;/span&gt;
  &lt;span class="comment"&gt;#   end&lt;/span&gt;

  &lt;span class="comment"&gt;# You can have the root of your site routed with map.root -- just remember to delete public/index.html.&lt;/span&gt;
  &lt;span class="comment"&gt;# map.root :controller =&amp;gt; &amp;quot;welcome&amp;quot;&lt;/span&gt;

  &lt;span class="comment"&gt;# See how all your routes lay out with &amp;quot;rake routes&amp;quot;&lt;/span&gt;

  &lt;span class="comment"&gt;# Install the default routes as the lowest priority.&lt;/span&gt;
  &lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;:controller/:action/:id&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;:controller/:action/:id.:format&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Ah, when we generated the resources, they edited the same line on the file.  That&amp;#8217;s an easy fix.  Just get rid of the conflict markers.  Merge again.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git add .
&amp;gt; git commit -m 'Merged from comment branch.  Resolved config/routes.rb'
Created commit cfb3b0e: Merged from comment branch.  Resolved config/routes.rb
 8 files changed, 49 insertions(+), 0 deletions(-)
 create mode 100644 app/controllers/comments_controller.rb
 create mode 100644 app/helpers/comments_helper.rb
 create mode 100644 app/models/comment.rb
 create mode 100644 db/migrate/001_create_comments.rb
 create mode 100644 test/fixtures/comments.yml
 create mode 100644 test/functional/comments_controller_test.rb
 create mode 100644 test/unit/comment_test.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now we have both Post and Comment resources in our master branch.  At this point, we can delete the posts and comments branches.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git branch -d posts
Deleted branch posts.
&amp;gt; git branch -d comments
error: The branch 'comments' is not an ancestor of your current HEAD.
If you are sure you want to delete it, run 'git branch -D comments'.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Since we manually merge and fix the conflict, Git is complaining that it is unsafe to delete the comments branch since we could lose some unmerged changes.  But we know we already have them in the master branch.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git branch -D comments
Deleted branch comments.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Lets establish some ActiveRecord relationships.  Before we do that, lets create another branch called relationships.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git branch relationships
&amp;gt; git checkout relationships
Switched to branch &amp;quot;relationships&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Add the one-to-many relationship to post.rb.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Post&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:comments&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;At this point, lets assume our customer notifies us there is an urgent bug in the master branch.  We want to make them happy, so we will temporarily suspend our work in the relationships branch and fix the bug in the master branch, before we come back to finish our work in the relationships branch.&lt;/p&gt;


	&lt;p&gt;We use a stash to do that.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git stash save
Saved working directory and index state &amp;quot;WIP on relationships: cfb3b0e... Merged from comment branch.  Resolved config/routes.rb&amp;quot;
HEAD is now at cfb3b0e... Merged from comment branch.  Resolved config/routes.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The git-stash man page says:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Use git-stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory.  The command saves your local modifications away and reverts the working directory to match the &lt;span class="caps"&gt;HEAD&lt;/span&gt; commit.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;A few more stash commands.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git stash list
stash@{0}: WIP on relationships: cfb3b0e... Merged from comment branch. Resolved config/routes.rb
&amp;gt; git stash show
 app/models/post.rb |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
&amp;gt; git stash show -p
diff --git a/app/models/post.rb b/app/models/post.rb
index 791dcb5..6ad2382 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -1,2 +1,3 @@
 class Post &amp;lt; ActiveRecord::Base
+  has_many :comments
 end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Our changes are now saved to the stash, as evidenced by running git status.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git status
# On branch relationships
nothing to commit (working directory clean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Lets fix the urgent bug in the master branch.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git checkout master
Switched to branch &amp;quot;master&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;It turns out the bug is really trivial.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; rm public/index.html
&amp;gt; git commit -a -m 'Fixed urgent bug'
Created commit 9a6dcf7: Fixed urgent bug
 1 files changed, 0 insertions(+), 277 deletions(-)
 delete mode 100644 public/index.html&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;We can resume our work in the relationships branch now.  We need to retrieve the work we have done so far in the branch from the stash.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git checkout relationships
Switched to branch &amp;quot;relationships&amp;quot;
&amp;gt; git stash apply
# On branch relationships
# Changed but not updated:
#   (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)
#
#    modified:   app/models/post.rb
#
no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Lets finish our relationship modeling by modifying comment.rb&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Comment&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;belongs_to&lt;/span&gt; &lt;span class="symbol"&gt;:post&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;We are ready to commit our changes now.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git commit -a -m 'Added post-comment relationship'
Created commit f71752b: Added post-comment relationship
 2 files changed, 2 insertions(+), 0 deletions(-)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;A quick peek at gitk.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://img.skitch.com/20080427-musar19kcq4ftdin6aht12qkaq.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;We can merge the relationships branch to the master branch now.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git checkout master
Switched to branch &amp;quot;master&amp;quot;
&amp;gt; git merge relationships
Merge made by recursive.
 app/models/comment.rb |    1 +
 app/models/post.rb    |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)
&amp;gt; git branch -d relationships
Deleted branch relationships.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;We can now clear our stash because we already have the changes.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;gt; git stash clear&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Final picture.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://img.skitch.com/20080427-n7u84ucaks6igsqisk3e6mkmkj.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Yay!&lt;/p&gt;</description>
      <pubDate>Sun, 27 Apr 2008 10:50:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:26f903a9-5cfd-4aad-87c5-f9378d5836dc</guid>
      <author>Raymond Law</author>
      <link>http://blog.rayvinly.com/articles/2008/04/27/using-git-branches-and-stash</link>
      <category>Git</category>
      <category>Ruby on Rails</category>
      <category>Web 2.0</category>
      <category>git</category>
      <category>ruby</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <trackback:ping>http://blog.rayvinly.com/articles/trackback/60</trackback:ping>
    </item>
  </channel>
</rss>
