<?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" xml:lang="en-US">
  <title>has_many :bugs, :through =&gt; :rails - Home</title>
  <id>tag:m.onkey.org,2009:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  
  <link href="http://m.onkey.org/" rel="alternate" type="text/html" />
  <updated>2009-07-07T22:21:55Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/monkeyonrails" type="application/atom+xml" /><entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2009-07-07:10281</id>
    <published>2009-07-07T22:21:00Z</published>
    <updated>2009-07-07T22:21:55Z</updated>
    <category term="rails" />
    <category term="views" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/PNx7Qzmxllg/nested-layouts" rel="alternate" type="text/html" />
    <title>Nested Layouts</title>
<content type="html">
            &lt;p&gt;Don’t think the nested layouts get any simpler in Rails.&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;ApplicationHelper&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;parent_layout&lt;/span&gt;(layout)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@content_for_layout&lt;/span&gt; = &lt;span class="pc"&gt;self&lt;/span&gt;.output_buffer&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pc"&gt;self&lt;/span&gt;.output_buffer = render(&lt;span class="sy"&gt;:file&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;layouts/&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;layout&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Now using the &lt;i&gt;parent_layout&lt;/i&gt; helper method inside your layouts for nesting :&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# items.html.erb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;h1&amp;gt;&lt;span class="co"&gt;Just&lt;/span&gt; my items&amp;lt;&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;h1&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;%= yield %&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;% parent_layout 'master' %&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;and the parent layout of &lt;em&gt;items&lt;/em&gt; – the &lt;em&gt;master&lt;/em&gt; layout :&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# master.html.erb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;html xmlns=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/1999/xhtml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; xml&lt;span class="sy"&gt;:lang=&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; lang=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&lt;span class="co"&gt;Hello&lt;/span&gt; &lt;span class="co"&gt;World&lt;/span&gt;&amp;lt;&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;title&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;head&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;body&amp;gt;&lt;tt&gt;
&lt;/tt&gt;    &amp;lt;%= &lt;span class="r"&gt;yield&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;/body&lt;/span&gt;&lt;span class="dl"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Now, the &lt;em&gt;items&lt;/em&gt; layout will always be wrapped under the &lt;em&gt;master&lt;/em&gt; layout. &lt;strong&gt;Just make sure that the &lt;i&gt;parent_layout&lt;/i&gt; call is always on the last line using &amp;lt;%&lt;/strong&gt;. This technique also works for nesting deeper than a single level.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=PNx7Qzmxllg:96cUfiv9Fxs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=PNx7Qzmxllg:96cUfiv9Fxs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=PNx7Qzmxllg:96cUfiv9Fxs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=PNx7Qzmxllg:96cUfiv9Fxs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=PNx7Qzmxllg:96cUfiv9Fxs:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=PNx7Qzmxllg:96cUfiv9Fxs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/PNx7Qzmxllg" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2009/7/7/nested-layouts</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2009-04-22:7832</id>
    <published>2009-04-22T23:40:00Z</published>
    <updated>2009-04-22T23:41:12Z</updated>
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/2a_NjmvUmC0/announcing-actionrails" rel="alternate" type="text/html" />
    <title>Announcing ActionRails</title>
<content type="html">
            &lt;p&gt;I’m very happy to announce &lt;a href="http://www.actionrails.com"&gt;ActionRails&lt;/a&gt; – a new consulting firm jointly owned by &lt;a href="http://therailsway.com"&gt;Koz&lt;/a&gt; (Rails core, therailsway.com author), &lt;a href="http://afreshcup.com"&gt;Mike Gunderloy&lt;/a&gt; (Rails documentation/activist team) and myself.&lt;/p&gt;
&lt;p&gt;ActionRails is not trying to be yet another consultancy that develops applications from start to finish (though we can talk to you individually about such projects). Rather, we have a distinct set of services, designed to help customers complete successful Rails deployments and helping existing teams improve their Rails skills. Our menu currently offers:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Application Evaluation&lt;/li&gt;
	&lt;li&gt;Weekly Code Reviews&lt;/li&gt;
	&lt;li&gt;Developer Hotline&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ActionRails has already been working for a few select clients, helping them out with reviewing code, offering course corrections, and evaluating application architecture (among other things). You can hop over to &lt;a href="http://www.actionrails.com"&gt;our site&lt;/a&gt; for more information, or just &lt;a href="http://www.actionrails.com/contact.html"&gt;drop us a line&lt;/a&gt;.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=2a_NjmvUmC0:ixBX_hsFAKM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=2a_NjmvUmC0:ixBX_hsFAKM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=2a_NjmvUmC0:ixBX_hsFAKM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=2a_NjmvUmC0:ixBX_hsFAKM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=2a_NjmvUmC0:ixBX_hsFAKM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=2a_NjmvUmC0:ixBX_hsFAKM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/2a_NjmvUmC0" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2009/4/22/announcing-actionrails</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2009-03-24:7464</id>
    <published>2009-03-24T10:28:00Z</published>
    <updated>2009-03-24T11:01:44Z</updated>
    <category term="activerecord" />
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/w-YQF0s6gyY/default-scopes-and-inheritance-to-the-rescue" rel="alternate" type="text/html" />
    <title>Default Scopes and Inheritance to the rescue</title>
<content type="html">
            &lt;p&gt;On my one of the current projects, there are two primary models each with a flag called &lt;em&gt;approved&lt;/em&gt;. 99% of the front end part deals with only approved items. Unapproved items are usually only in the admin panel side of the story. So I started with using a &lt;i&gt;named_scope&lt;/i&gt; called &lt;em&gt;approved&lt;/em&gt;:&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Item&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has_many &lt;span class="sy"&gt;:tags&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  default_scope &lt;span class="sy"&gt;:order&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;items.name ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  named_scope &lt;span class="sy"&gt;:approved&lt;/span&gt;, &lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; { &lt;span class="sy"&gt;:published&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;And now I’d have to use &lt;em&gt;Item.approved.&amp;lt;whatever&gt;&lt;/em&gt; everywhere in my application. But that became a bit too cumbersome sooner than later. Playing around with this a bit, I came up with the solution using &lt;i&gt;default_scope&lt;/i&gt; and the good ol’ inheritance:&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Item&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has_many &lt;span class="sy"&gt;:tags&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  default_scope &lt;span class="sy"&gt;:order&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;items.name ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;PublishedItem&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;Item&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  set_table_name &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;items&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  set_inheritance_column &lt;span class="pc"&gt;nil&lt;/span&gt; &lt;span class="c"&gt;# hax?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  default_scope &lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; { &lt;span class="sy"&gt;:published&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt; }, &lt;span class="sy"&gt;:order&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;items.name ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Checking this on console :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&gt;&gt; p = PublishedItem.first
  SELECT * FROM `items` WHERE (`items`.`published` = 1) ORDER BY items.name ASC LIMIT 1

&gt;&gt; i = Item.first
  SELECT * FROM `items` ORDER BY items.name ASC LIMIT 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Seems to work just fine.&lt;/p&gt;
&lt;p&gt;You could do it the other way around too:&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;RawItem&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  set_table_name &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;items&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has_many &lt;span class="sy"&gt;:tags&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  default_scope &lt;span class="sy"&gt;:order&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;items.name ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Item&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;RawItem&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  set_table_name &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;items&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  set_inheritance_column &lt;span class="pc"&gt;nil&lt;/span&gt; &lt;span class="c"&gt;# hax?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  default_scope &lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; { &lt;span class="sy"&gt;:published&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt; }, &lt;span class="sy"&gt;:order&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;items.name ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Whichever one works for you.&lt;/p&gt;
&lt;p&gt;Please note that the above code is &lt;em&gt;&lt;span class="caps"&gt;NOT&lt;/span&gt;&lt;/em&gt; using &lt;em&gt;&lt;span class="caps"&gt;STI&lt;/span&gt;&lt;/em&gt;. It’s using &lt;i&gt;set_inheritance_column nil&lt;/i&gt; workaround to bypass the Active Record &lt;span class="caps"&gt;STI&lt;/span&gt; stuff and rely just on the ruby inheritance.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=w-YQF0s6gyY:6v2oJCG1A3E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=w-YQF0s6gyY:6v2oJCG1A3E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=w-YQF0s6gyY:6v2oJCG1A3E:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=w-YQF0s6gyY:6v2oJCG1A3E:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=w-YQF0s6gyY:6v2oJCG1A3E:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=w-YQF0s6gyY:6v2oJCG1A3E:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/w-YQF0s6gyY" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2009/3/24/default-scopes-and-inheritance-to-the-rescue</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2009-03-18:7385</id>
    <published>2009-03-18T12:42:00Z</published>
    <updated>2009-03-18T12:42:21Z</updated>
    <category term="documentation" />
    <category term="guides" />
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/SPW-aviw1aU/my-rails-guides" rel="alternate" type="text/html" />
    <title>My Rails guides</title>
<content type="html">
            &lt;p&gt;Instead of blogging some of the articles, I decided to write those as Rails guides. So go ahead and check them out !&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://guides.rubyonrails.org/rails_on_rack.html"&gt;Rails on Rack&lt;/a&gt; – Overview of Rails’ Rack integration and middleware/metal interfaces&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://guides.rubyonrails.org/performance_testing.html"&gt;Performance Testing Rails Applications&lt;/a&gt; – Using Rails’ built in performance test suite for profiling and benchmarking your Rails application&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also wrote a lot of the &lt;a href="http://guides.rubyonrails.org/active_record_querying.html"&gt;Active Record Query Interface&lt;/a&gt; guide. Of course my guides aren’t really eligible for the &lt;a href="http://hackfest.rubyonrails.org"&gt;guides hackfest prizes&lt;/a&gt;. But hey, you could still win them by &lt;a href="http://guides.rubyonrails.org/contribute.html"&gt;writing a new guide&lt;/a&gt; !&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=SPW-aviw1aU:NzBOnoTrvEY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=SPW-aviw1aU:NzBOnoTrvEY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=SPW-aviw1aU:NzBOnoTrvEY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=SPW-aviw1aU:NzBOnoTrvEY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=SPW-aviw1aU:NzBOnoTrvEY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=SPW-aviw1aU:NzBOnoTrvEY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/SPW-aviw1aU" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2009/3/18/my-rails-guides</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2009-03-17:7368</id>
    <published>2009-03-17T15:49:00Z</published>
    <updated>2009-03-17T15:50:03Z</updated>
    <category term="testing" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/LbPCQlg32qo/assert_-and-assert_not_" rel="alternate" type="text/html" />
    <title>assert_* and assert_not_*</title>
<content type="html">
            &lt;p&gt;Not sure I like this or not, but I’m gonna give it a shot in the “real world” nevertheless.&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;AssertionExtensions&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;method_missing&lt;/span&gt;(method_id, *arguments, &amp;amp;block)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="r"&gt;super&lt;/span&gt; &lt;span class="r"&gt;unless&lt;/span&gt; method_id.to_s =~ &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^assert_(not_)?(.*)$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;    method = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="gv"&gt;$2&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;?&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    object = arguments.first&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="gv"&gt;$1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      arguments.each &lt;span class="r"&gt;do&lt;/span&gt; |object|&lt;tt&gt;
&lt;/tt&gt;        assert ! object.send(method), &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;method&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; is not false for &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;object&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      arguments.each &lt;span class="r"&gt;do&lt;/span&gt; |object|&lt;tt&gt;
&lt;/tt&gt;        assert object.send(method), &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;method&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; is not true for &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;object&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ActiveSupport::TestCase&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class="co"&gt;AssertionExtensions&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Now using this in your tests:&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;test_is_admin&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# [people(:admin), people(:superuser)].each {|p| assert p.admin?}&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  assert_admin people(&lt;span class="sy"&gt;:admin&lt;/span&gt;), people(&lt;span class="sy"&gt;:superuser&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# assert ! people(:foo).admin?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  assert_not_admin people(&lt;span class="sy"&gt;:foo&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=LbPCQlg32qo:axlHA3N3pZY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=LbPCQlg32qo:axlHA3N3pZY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=LbPCQlg32qo:axlHA3N3pZY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=LbPCQlg32qo:axlHA3N3pZY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=LbPCQlg32qo:axlHA3N3pZY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=LbPCQlg32qo:axlHA3N3pZY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/LbPCQlg32qo" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2009/3/17/assert_-and-assert_not_</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2009-03-14:7320</id>
    <published>2009-03-14T12:51:00Z</published>
    <updated>2009-03-14T12:51:38Z</updated>
    <category term="testing" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/c4GQb4wg8EI/some-t-u" rel="alternate" type="text/html" />
    <title>Make Test::Unit display errors earlier</title>
<content type="html">
            &lt;p&gt;Just a monkey patch to make &lt;em&gt;Test::Unit&lt;/em&gt; display errors as soon as they happen.&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;test/unit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;test/unit/ui/console/testrunner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Test::Unit::UI::Console::TestRunner&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;add_fault&lt;/span&gt;(fault)&lt;tt&gt;
&lt;/tt&gt;    hax_output(fault)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@faults&lt;/span&gt; &amp;lt;&amp;lt; fault&lt;tt&gt;
&lt;/tt&gt;    output_single(fault.single_character_display, &lt;span class="i"&gt;1&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@already_outputted&lt;/span&gt; = &lt;span class="pc"&gt;true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;hax_output&lt;/span&gt;(fault)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@io&lt;/span&gt;.puts(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    output_single(fault.short_display, &lt;span class="i"&gt;1&lt;/span&gt;) &lt;span class="c"&gt;# fault.long_display for the full trace&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@io&lt;/span&gt;.puts(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;Useful when your tests take too long to run.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=c4GQb4wg8EI:uO--XvU7f7g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=c4GQb4wg8EI:uO--XvU7f7g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=c4GQb4wg8EI:uO--XvU7f7g:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=c4GQb4wg8EI:uO--XvU7f7g:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=c4GQb4wg8EI:uO--XvU7f7g:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=c4GQb4wg8EI:uO--XvU7f7g:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/c4GQb4wg8EI" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2009/3/14/some-t-u</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2009-01-15:5774</id>
    <published>2009-01-15T17:54:00Z</published>
    <updated>2009-01-16T02:15:28Z</updated>
    <category term="rack" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/TKSHESfZlmw/the-evil-calls-back" rel="alternate" type="text/html" />
    <title>The Evil calls back</title>
<content type="html">
            &lt;p&gt;Happy new year!&lt;/p&gt;


	&lt;p&gt;Just an update on the two middlewares I contributed to &lt;a href="http://github.com/rack/rack-contrib/tree/master"&gt;rack-contrib&lt;/a&gt;. In case you don’t already know what is &lt;a href="http://github.com/rtomayko/rack-contrib"&gt;rack-contrib&lt;/a&gt;, it’s a project started by &lt;a href="http://tomayko.com"&gt;Ryan Tomayko&lt;/a&gt; as a playground for experimental Rack middlewares from the ruby community. There are 15 middlewares there already, so do check it out!&lt;/p&gt;


	&lt;h2&gt;Rack::Evil&lt;/h2&gt;


	&lt;p&gt;The name says it all. It’s pure evil, as it enables the rack application to return the response from any place during while it’s serving the request by doing &lt;strong&gt;&lt;em&gt;throw :response, [status, header, body]&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;Example:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;app = lambda &lt;span class="r"&gt;do&lt;/span&gt; |env|&lt;tt&gt;
&lt;/tt&gt;  template = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;lt;&amp;lt;-TEMPLATE&lt;/span&gt;&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;  Hello Template&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;%= throw :response, [404, {'Content-Type' =&amp;gt; 'text/html'}, 'From Template'] %&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  Never&lt;/span&gt;&lt;span class="dl"&gt;&lt;tt&gt;
&lt;/tt&gt;  TEMPLATE&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  result = &lt;span class="co"&gt;ERB&lt;/span&gt;.new(template).result(binding)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Ran the template&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And the response reaching the client will not be “&lt;em&gt;Ran the template&lt;/em&gt;” with &lt;em&gt;200&lt;/em&gt; status. But it’ll be “&lt;em&gt;From Template&lt;/em&gt;” with &lt;em&gt;404&lt;/em&gt; status!&lt;/p&gt;


	&lt;h2&gt;Rack::Callbacks&lt;/h2&gt;


	&lt;p&gt;Now that more people are getting on board with the concept of &lt;em&gt;middlewares&lt;/em&gt;, people have started using middlewares for pure &lt;em&gt;before/after&lt;/em&gt; filter kind of things. And I think don’t think that’s the best way moving forward. That’s the problem &lt;em&gt;Rack::Callbacks&lt;/em&gt; tries to alleviate.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Rack::Callbacks&lt;/em&gt; lets you wrap your rack application with a series of &lt;em&gt;before&lt;/em&gt; and &lt;em&gt;after&lt;/em&gt; callbacks.&lt;/p&gt;


	&lt;p&gt;Example :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;TimeZone&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;initialize&lt;/span&gt;(default)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@default&lt;/span&gt; = default&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;call&lt;/span&gt;(env)&lt;tt&gt;
&lt;/tt&gt;    env[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rack.timezone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;] = find_timezone(env) || &lt;span class="iv"&gt;@default&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CompressBody&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;call&lt;/span&gt;(response)&lt;tt&gt;
&lt;/tt&gt;    status, headers, body = response&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    compressed_body = zip_body(body)&lt;tt&gt;
&lt;/tt&gt;    [status, headers, compressed_body]&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;app = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Callbacks&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  before &lt;span class="co"&gt;TimeZone&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  run &lt;span class="co"&gt;YourPrimaryRackApp&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  after &lt;span class="co"&gt;CompressBody&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The flow of execution is very apparent here. All the before callbacks are run first, then the actual application and after callbacks at last.&lt;/p&gt;


	&lt;h4&gt;before Callback, arg1, arg2….argx&lt;/h4&gt;


	&lt;p&gt;&lt;em&gt;before()&lt;/em&gt; takes &lt;em&gt;Callback&lt;/em&gt; class as the first argument. Optional arguments are passed to &lt;em&gt;Callback#initialize&lt;/em&gt;. This is very similar to the regular rack middlewares. However &lt;em&gt;before&lt;/em&gt; callbacks are quite different from middlewares.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Callback#call&lt;/em&gt; accepts a single argument : &lt;em&gt;env&lt;/em&gt;. However, the return value of &lt;em&gt;Callback#call&lt;/em&gt; is simply discarded.&lt;/p&gt;


	&lt;h4&gt;run Application&lt;/h4&gt;


	&lt;p&gt;Runs the primary rack application.&lt;/p&gt;


	&lt;h4&gt;after Callback, arg1, arg2….argx&lt;/h4&gt;


	&lt;p&gt;&lt;em&gt;after()&lt;/em&gt; takes &lt;em&gt;Callback&lt;/em&gt; class as the first argument. Optional arguments are passed to &lt;em&gt;Callback#initialize&lt;/em&gt;. Just like &lt;em&gt;before()&lt;/em&gt; and &lt;em&gt;middlewares&lt;/em&gt;. However, &lt;em&gt;after&lt;/em&gt; callbacks are substantially different from &lt;em&gt;before callbacks&lt;/em&gt; and &lt;em&gt;middlewares&lt;/em&gt;:&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Callback#call&lt;/em&gt; accepts a single argument : &lt;em&gt;response&lt;/em&gt;, which is the rack response returned by the application or other &lt;em&gt;after filters&lt;/em&gt;. &lt;em&gt;Callback#call&lt;/em&gt; also must return a valid rack response. Return value of &lt;em&gt;Callback#call&lt;/em&gt; is supplied to the next &lt;em&gt;after filters&lt;/em&gt; in the stack, and the final &lt;em&gt;after filter&lt;/em&gt; returns the response to the client.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=vGZ59pBv"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=vGZ59pBv" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=9xja9Na7"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=9xja9Na7" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=PTupZtcT"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=J8SkwaGs"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/TKSHESfZlmw" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2009/1/15/the-evil-calls-back</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2008-12-04:3396</id>
    <published>2008-12-04T00:50:00Z</published>
    <updated>2008-12-07T04:16:53Z</updated>
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/71GZ3XsoZbk/rails-templates" rel="alternate" type="text/html" />
    <title>Rails templates</title>
<content type="html">
            &lt;p&gt;So now that &lt;strong&gt;Edge Rails&lt;/strong&gt; got &lt;a href="http://github.com/rails/rails/commit/e8cc4b116c460c524961a07da92da3f323854c15"&gt;templates&lt;/a&gt; ( Thanks to &lt;a href="http://www.omgbloglol.com"&gt;Jeremy&lt;/a&gt; ) I just wanted to give a top level overview.&lt;/p&gt;


	&lt;p&gt;Templates are simple &lt;strong&gt;ruby&lt;/strong&gt; files containing &lt;span class="caps"&gt;DSL&lt;/span&gt; for adding plugins/gems/initializers etc. to your freshly created Rails project. To apply the template, you need to provide rails generator with location of the template you wish to apply, using &lt;em&gt;-m&lt;/em&gt; option :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rails blog -m ~&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;template.rb&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Thanks to the magic of &lt;em&gt;open-uri&lt;/em&gt;, the template location can be a &lt;span class="caps"&gt;URL&lt;/span&gt; too :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rails blog -m http&lt;span class="sy"&gt;:/&lt;/span&gt;/gist.github.com/&lt;span class="i"&gt;31208&lt;/span&gt;.txt&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;You can even apply templates to your existing Rails application using &lt;em&gt;rails:template&lt;/em&gt; rake task and supplying &lt;em&gt;&lt;span class="caps"&gt;LOCATION&lt;/span&gt;&lt;/em&gt; environment variable :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rake rails&lt;span class="sy"&gt;:template&lt;/span&gt; &lt;span class="co"&gt;LOCATION&lt;/span&gt;=~&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;template.rb&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;A very simple template would look like :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# template.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;run &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;rm public/index.html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;generate(&lt;span class="sy"&gt;:scaffold&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;person name:string&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;route &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;map.root :controller =&amp;gt; 'people'&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;rake(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;db:migrate&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;git &lt;span class="sy"&gt;:init&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;git &lt;span class="sy"&gt;:add&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;git &lt;span class="sy"&gt;:commit&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;-a -m 'Initial commit'&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;That’s very self explanatory. Here are the key methods for the template &lt;span class="caps"&gt;DSL&lt;/span&gt; :&lt;/p&gt;


	&lt;h4&gt;gem(name, options = {})&lt;/h4&gt;


	&lt;p&gt;Adds a &lt;em&gt;config.gem&lt;/em&gt; entry for the supplied gem  to generated application’s &lt;em&gt;config/environment.rb&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;So if your application depends on &lt;em&gt;bj&lt;/em&gt; and &lt;em&gt;hpricot&lt;/em&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;gem &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;bj&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;gem &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hpricot&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:version&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;0.6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:source&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://code.whytheluckystiff.net&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Please note that this will &lt;em&gt;&lt;span class="caps"&gt;NOT&lt;/span&gt;&lt;/em&gt; install the gems for you. So you may want to run &lt;em&gt;rake gems:install&lt;/em&gt;:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rake &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;gems:install&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And let Rails take care of installing the required gems if they’re not already installed.&lt;/p&gt;


	&lt;h4&gt;plugin(name, options = {})&lt;/h4&gt;


	&lt;p&gt;Installs a plugin to the generated application.&lt;/p&gt;


	&lt;p&gt;Plugin can be installed from Git :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;authentication&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;git://github.com/foor/bar.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;You can even install plugins as git submodules :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;authentication&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;git://github.com/foor/bar.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:submodule&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;&lt;em&gt;Please note that you need to git :init before you can install a plugin as a submodule&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Or use plain old &lt;span class="caps"&gt;SVN&lt;/span&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;wtfsvn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="sy"&gt;:svn&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;svn://crap.com/wtf/trunk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h4&gt;initializer(filename, data = nil, &amp;block)&lt;/h4&gt;


	&lt;p&gt;Adds an initializer to the generated application’s &lt;em&gt;config/initializers&lt;/em&gt; directory.&lt;/p&gt;


	&lt;p&gt;So personally, I like using Object#not_nil? and Object#not_blank? :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;initializer &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;bloatlol.rb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;lt;&amp;lt;-CODE&lt;/span&gt;&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;class Object&lt;tt&gt;
&lt;/tt&gt;  def not_nil?&lt;tt&gt;
&lt;/tt&gt;    !nil?&lt;tt&gt;
&lt;/tt&gt;  end&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  def not_blank?&lt;tt&gt;
&lt;/tt&gt;    !blank?&lt;tt&gt;
&lt;/tt&gt;  end&lt;tt&gt;
&lt;/tt&gt;end&lt;/span&gt;&lt;span class="dl"&gt;&lt;tt&gt;
&lt;/tt&gt;CODE&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Similarly &lt;em&gt;&lt;strong&gt;lib()&lt;/strong&gt;&lt;/em&gt; creates a file in &lt;em&gt;lib/&lt;/em&gt; directory and &lt;em&gt;&lt;strong&gt;vendor()&lt;/strong&gt;&lt;/em&gt; creates a file in &lt;em&gt;vendor/&lt;/em&gt; directory. There is also &lt;em&gt;file()&lt;/em&gt;, which accepts a relative path from &lt;em&gt;&lt;span class="caps"&gt;RAILS&lt;/span&gt;_ROOT&lt;/em&gt; and creates all the directories/file needed :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;file &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;app/components/foo.rb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;lt;&amp;lt;-CODE&lt;/span&gt;&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;class Foo&lt;tt&gt;
&lt;/tt&gt;end&lt;/span&gt;&lt;span class="dl"&gt;&lt;tt&gt;
&lt;/tt&gt;CODE&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;That’ll create &lt;em&gt;app/components&lt;/em&gt; directory and put &lt;em&gt;foo.rb&lt;/em&gt; in there.&lt;/p&gt;


	&lt;h4&gt;rakefile(filename, data = nil, &amp;block)&lt;/h4&gt;


	&lt;p&gt;Creates a new rake file under &lt;em&gt;lib/tasks&lt;/em&gt; with the supplied tasks :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rakefile(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;bootstrap.rake&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;lt;&amp;lt;-TASK&lt;/span&gt;&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;    namespace :boot do&lt;tt&gt;
&lt;/tt&gt;      task :strap do&lt;tt&gt;
&lt;/tt&gt;        puts &amp;quot;i like boots!&amp;quot;&lt;tt&gt;
&lt;/tt&gt;      end&lt;tt&gt;
&lt;/tt&gt;    end&lt;/span&gt;&lt;span class="dl"&gt;&lt;tt&gt;
&lt;/tt&gt;  TASK&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And that creates &lt;em&gt;lib/tasks/bootstrap.rake&lt;/em&gt; with a &lt;em&gt;boot:strap&lt;/em&gt; rake task!&lt;/p&gt;


&lt;h4&gt;generate(what, args)&lt;/h4&gt;

	&lt;p&gt;Runs the supplied rails generator with given arguments. For example, I love to scaffold some whenever I’m playing with Rails :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;generate(&lt;span class="sy"&gt;:scaffold&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;person&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;name:string&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;address:text&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;age:number&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h4&gt;run(command)&lt;/h4&gt;


	&lt;p&gt;Executes an arbitrary command. Just like the backticks. My main use case is to remove &lt;em&gt;public/index.html&lt;/em&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;run &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;rm public/index.html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h4&gt;rake(command, options = {})&lt;/h4&gt;


	&lt;p&gt;So you scaffolded, but who’s gonna run the &lt;em&gt;db:migrate&lt;/em&gt; rake task !? Here’s who :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rake &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;db:migrate&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Simple enough.&lt;/p&gt;


	&lt;p&gt;You can also run rake tasks in a different rails environment :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rake &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;db:migrate&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:env&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Or even use sudo :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rake &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;gems:install&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:sudo&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h4&gt;route(routing_code)&lt;/h4&gt;


	&lt;p&gt;This adds a routing entry to &lt;em&gt;config/routes.rb&lt;/em&gt; file. In above steps, we generated a &lt;em&gt;person&lt;/em&gt; scaffold and also removed &lt;em&gt;public/index.html&lt;/em&gt;. Now to make &lt;em&gt;PeopleController#index&lt;/em&gt; as the default page for the application :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;route &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;map.root :controller =&amp;gt; :person&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Voila!&lt;/p&gt;


	&lt;h4&gt;inside(dir)&lt;/h4&gt;


	&lt;p&gt;I have my edge rails lying at &lt;em&gt;~/commit-rails/rails&lt;/em&gt;. So every time i have to manually symlink edge from my new app. But now :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;inside(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;vendor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  run &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;ln -s ~/commit-rails/rails rails&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;So &lt;em&gt;inside()&lt;/em&gt; runs the command from the given directory.&lt;/p&gt;


	&lt;h4&gt;ask(question)&lt;/h4&gt;


	&lt;p&gt;&lt;em&gt;ask&lt;/em&gt; gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;lib_name = ask(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;What do you want to call the shiny library ?&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;lib_name &amp;lt;&amp;lt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;.rb&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;unless&lt;/span&gt; lib_name.index(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;.rb&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;lib lib_name, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;lt;&amp;lt;-CODE&lt;/span&gt;&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;class Shiny&lt;tt&gt;
&lt;/tt&gt;end&lt;/span&gt;&lt;span class="dl"&gt;&lt;tt&gt;
&lt;/tt&gt;CODE&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h4&gt;yes?(question) or no?(question)&lt;/h4&gt;


	&lt;p&gt;And you can even ask questions from templates and decide the flow based on user’s answer. Lets say you want to freeze rails only if the user want to :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rake(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;rails:freeze:gems&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;if&lt;/span&gt; yes?(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Freeze rails gems ?&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;&lt;em&gt;&lt;strong&gt;no?(question)&lt;/strong&gt;&lt;/em&gt; acts just the opposite.&lt;/p&gt;


	&lt;h4&gt;git(:must =&amp;gt; “-a love”)&lt;/h4&gt;


	&lt;p&gt;As we all love git/hub, Rails templates let you do the git stuff too !&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;git &lt;span class="sy"&gt;:init&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;git &lt;span class="sy"&gt;:add&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;git &lt;span class="sy"&gt;:commit&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;-a -m 'Initial commit'&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h2&gt;And bort ?&lt;/h2&gt;


	&lt;p&gt;Here’s what a bort template would look like :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# bort.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;inside(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;vendor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  run &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;ln -s ~/commit-rails/rails rails&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;git://github.com/dchelimsky/rspec.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec-rails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;git://github.com/dchelimsky/rspec-rails.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;exception_notifier&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;git://github.com/rails/exception_notification.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;open_id_authentication&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;git://github.com/rails/open_id_authentication.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;asset_packager&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;http://synthesis.sbecker.net/pages/asset_packager&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;role_requirement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;git://github.com/timcharper/role_requirement.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;plugin &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;restful-authentication&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:git&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;git://github.com/technoweenie/restful-authentication.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;gem &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;mislav-will_paginate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:version&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;~&amp;gt; 2.2.3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:lib&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;will_paginate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,  &lt;span class="sy"&gt;:source&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;http://gems.github.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;gem &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rubyist-aasm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;gem &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;ruby-openid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;rake(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;gems:install&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="sy"&gt;:sudo&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;generate(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;authenticated&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;user session&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;generate(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;rspec&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Shamelessly inspired/yanked from &lt;a href="http://github.com/jeremymcanally/rails-templates/tree/master/bort.template"&gt;Jeremy’s templates repo&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Save that code in &lt;em&gt;bort.rb&lt;/em&gt; and :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;[lifo&lt;span class="iv"&gt;@null&lt;/span&gt; &lt;span class="co"&gt;Rails&lt;/span&gt;]&lt;span class="er"&gt;$&lt;/span&gt; ruby ~&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;commit-rails&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;rails/railties/bin/rails bortapp -m bort.rb&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h2&gt;Contribute&lt;/h2&gt;


	&lt;p&gt;If you like this template stuff and want to share your templates with the rest of us, please contribute to &lt;a href="http://www.omgbloglol.com"&gt;Jeremy’s&lt;/a&gt; &lt;a href="http://github.com/jeremymcanally/rails-templates/tree/master"&gt;rails-templates project&lt;/a&gt; – which will be a collection of Rails templates.&lt;/p&gt;


	&lt;p&gt;And as usual, any bugs/feature requests can go to &lt;a href="http://rails.lighthouseapp.com"&gt;Rails lighthouse&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE 1&lt;/span&gt;&lt;/strong&gt; Add an example of installing plugins as a git submodule. Thanks to &lt;a href="http://www.petercooper.co.uk"&gt;Peter Cooper&lt;/a&gt; for the patch.
&lt;strong&gt;&lt;span class="caps"&gt;UPDATE 2&lt;/span&gt;&lt;/strong&gt; Add an example of &lt;em&gt;rake rails:template &lt;span class="caps"&gt;LOCATION&lt;/span&gt;=foo&lt;/em&gt; task&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=lUwbXtbP"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=lUwbXtbP" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=ne22EzIs"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=ne22EzIs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=BrBk9v6z"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=a37odHib"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/71GZ3XsoZbk" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2008/12/4/rails-templates</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2008-11-18:2926</id>
    <published>2008-11-18T01:34:00Z</published>
    <updated>2008-11-18T05:08:56Z</updated>
    <category term="rack" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/KRHZUdjTD6g/ruby-on-rack-2-rack-builder" rel="alternate" type="text/html" />
    <title>Ruby on Rack #2 - The Builder</title>
<content type="html">
            &lt;p&gt;In &lt;a href="http://m.onkey.org/2008/11/17/ruby-on-rack-1"&gt;Ruby on Rack #1 – Hello Rack!&lt;/a&gt; we used rackup to make port/server configurable. And rackup’s config file looked like :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# config.ru&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello Rack!&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Under the hood, &lt;em&gt;rackup&lt;/em&gt; converts your config script to an instance of &lt;a href="http://rack.rubyforge.org/doc/classes/Rack/Builder.html"&gt;Rack::Builder&lt;/a&gt;.&lt;/p&gt;


	&lt;h1&gt;What is Rack::Builder ?&lt;/h1&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Rack::Builder implements a small &lt;span class="caps"&gt;DSL&lt;/span&gt; to iteratively construct Rack applications.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;- &lt;a href="http://rack.rubyforge.org/doc/classes/Rack/Builder.html"&gt;Rack &lt;span class="caps"&gt;API&lt;/span&gt; Docs&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Rack::Builder&lt;/em&gt; is the thing that glues various Rack middlewares and applications together and convert them into a single entity/rack application. A good analogy is comparing Rack::Builder object with a &lt;em&gt;stack&lt;/em&gt;, where at the very bottom is your &lt;em&gt;actual&lt;/em&gt; rack application and all middlewares on top of it, and the whole stack itself is a rack application too.&lt;/p&gt;


	&lt;p&gt;Let’s say our rack application is called &lt;em&gt;infinity&lt;/em&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run infinity, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;All &lt;em&gt;infinity&lt;/em&gt; does is send the &lt;em&gt;env&lt;/em&gt; hash inspect string back to the browser.&lt;/p&gt;


	&lt;p&gt;Now, there are three important &lt;em&gt;Rack::Builder&lt;/em&gt; instance methods that you should care about :&lt;/p&gt;


	&lt;h4&gt;1. Rack::Builder#run&lt;/h4&gt;


	&lt;p&gt;&lt;em&gt;Rack::Builder#run&lt;/em&gt; specifies the actual rack application you’re wrapping with &lt;em&gt;Rack::Builder&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Converting &lt;em&gt;infinity&lt;/em&gt; to use &lt;em&gt;Rack::Builder&lt;/em&gt;:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;builder = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;builder.run infinity&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run builder, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Or you can follow the community convention and use the block form of &lt;em&gt;Rack::Builder&lt;/em&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;builder = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  run infinity&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run builder, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Here &lt;em&gt;Rack::Builder#initialize&lt;/em&gt; accepts a block argument, which is evaluated within the context of newly created instance using &lt;em&gt;instance_eval&lt;/em&gt;.&lt;/p&gt;


	&lt;h4&gt;2. Rack::Builder#use&lt;/h4&gt;


	&lt;p&gt;&lt;em&gt;Rack::Builder#use&lt;/em&gt; adds a middleware to the rack application stack created by &lt;em&gt;Rack::Builder&lt;/em&gt;. If the term &lt;em&gt;“middleware”&lt;/em&gt; confuses you, don’t worry. Hopefully my next post will clean the air. Stick to the before/after/around filter analogy for now.&lt;/p&gt;


	&lt;p&gt;Rack has many useful middlewares and one of them is &lt;em&gt;Rack::CommonLogger&lt;/em&gt;, which logs a single line to the supplied log file in the Apache common log format.&lt;/p&gt;


	&lt;p&gt;So if we’re to add &lt;em&gt;Rack::CommonLogger&lt;/em&gt; to &lt;em&gt;infinity&lt;/em&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;builder = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  use &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;CommonLogger&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  run infinity&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run builder, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Line of interest is of course &lt;em&gt;use Rack::CommonLogger&lt;/em&gt;. As we didn’t supply &lt;em&gt;Rack::CommonLogger&lt;/em&gt; with an explicit logger, by default it’ll log to &lt;em&gt;env[“rack.errors”]&lt;/em&gt;. Hence you’ll see logging strings in the console for every request.&lt;/p&gt;


	&lt;h4&gt;3. Rack::Builder#map&lt;/h4&gt;


	&lt;p&gt;&lt;em&gt;Rack::Builder#map&lt;/em&gt; mounts a stack of rack application/middlewares the specified path or &lt;span class="caps"&gt;URI&lt;/span&gt; and all the children paths under it.&lt;/p&gt;


	&lt;p&gt;Let’s say you want to show “infinity 0.1” for &lt;strong&gt;all the paths under &lt;em&gt;/version&lt;/em&gt;&lt;/strong&gt; ( i.e. /version, /version/whatever &lt;span class="caps"&gt;BUT NOT&lt;/span&gt; /versionsomething ) , you might want to do something like :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rubygems&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;builder = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  use &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;CommonLogger&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  run infinity&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;infinity 0.1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run builder, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;But that’s not going to work. &lt;em&gt;Rack::Builder#map&lt;/em&gt; also encapsulates a &lt;em&gt;scope&lt;/em&gt; within the builder. And &lt;strong&gt;one scope can just have one &lt;em&gt;Rack::Builder#run&lt;/em&gt; method&lt;/strong&gt;. In the example above, we have &lt;em&gt;run infinity&lt;/em&gt; at the top level global scope and &lt;em&gt;map ’/version’&lt;/em&gt; has it’s own &lt;em&gt;run&lt;/em&gt; too. Hence the conflict.&lt;/p&gt;


	&lt;p&gt;To fix this:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;builder = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  use &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;CommonLogger&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run infinity&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;infinity 0.1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run builder, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Now if you go to &lt;a href="http://localhost:9292/version"&gt;http://localhost:9292/version&lt;/a&gt; or &lt;a href="http://localhost:9292/version/1"&gt;http://localhost:9292/version/1&lt;/a&gt; or even &lt;a href="http://localhost:9292/version/whatever/doesnt/matter"&gt;http://localhost:9292/version/whatever/doesnt/matter&lt;/a&gt;, you’ll see “infinity 0.1” and for all the URIs not starting with &lt;em&gt;/version&lt;/em&gt; – &lt;a href="http://localhost:9292"&gt;http://localhost:9292&lt;/a&gt; – you’ll see the env hash inspect string!&lt;/p&gt;


	&lt;p&gt;Please note that :&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;&lt;em&gt;/versionsomething&lt;/em&gt;&lt;/strong&gt; WILL &lt;span class="caps"&gt;NOT&lt;/span&gt; show the version, but will display the env inspect.&lt;/li&gt;
		&lt;li&gt;When you have multiple &lt;em&gt;map&lt;/em&gt; blocks, URIs are tried from longest length to shortest length.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt;Nesting map blocks&lt;/h3&gt;


	&lt;p&gt;Let’s say you feel like adding information about last version. So to show “infinity beta 0.0” at &lt;em&gt;/version/last&lt;/em&gt;:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;builder = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  use &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;CommonLogger&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run infinity&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;infinity 0.1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/version/last&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;infinity beta 0.0&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run builder, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Above code will work perfectly as expected. You’ll see “infinity beta 0.0” at &lt;a href="http://localhost:9292/version/last"&gt;http://localhost:9292/version/last&lt;/a&gt; and “infinity 0.1” at &lt;a href="http://localhost:9292/version"&gt;http://localhost:9292/version&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;But a better way (&lt;em&gt;&lt;span class="caps"&gt;IMHO&lt;/span&gt;&lt;/em&gt;) to write the same code is by nesting map blocks :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;builder = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  use &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;CommonLogger&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run infinity&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;infinity 0.1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] }&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;    map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/last&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;infinity beta 0.0&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] }&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run builder, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This works perfect. When you nest map blocks, you’ll need to specify &lt;span class="caps"&gt;URI&lt;/span&gt; relative to the enclosing mapping block, as you can clearly see in the example above.&lt;/p&gt;


	&lt;h4&gt;Rack::Builder -&amp;gt; rackup&lt;/h4&gt;


	&lt;p&gt;As I mentioned above, &lt;em&gt;rackup&lt;/em&gt; converts the supplied rack config file to an instance of &lt;em&gt;Rack::Builder&lt;/em&gt;. This is how is happens under the hood ( just so you get an idea ) :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;config_file = &lt;span class="co"&gt;File&lt;/span&gt;.read(config)&lt;tt&gt;
&lt;/tt&gt;rack_application = eval(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Rack::Builder.new { &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;config_file&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; }&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And then &lt;em&gt;rackup&lt;/em&gt; supplies &lt;em&gt;rack_application&lt;/em&gt; to the respective webserver :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;server.run rack_application, options&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Very straight forward! In short, rack config files are evaluated within the context of a &lt;em&gt;Rack::Builder&lt;/em&gt; object. So if we convert &lt;em&gt;infinity&lt;/em&gt; to a rack config file which &lt;em&gt;rackup&lt;/em&gt; can understand :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# infinity.ru&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;infinity = &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, env.inspect]}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;use &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;CommonLogger&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  run infinity&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;infinity 0.1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/last&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;infinity beta 0.0&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And now run it :&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ rackup infinity.ru&lt;/code&gt;&lt;/pre&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=xg6RLL5s"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=xg6RLL5s" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=nBEc9lMJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=nBEc9lMJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=feXQVP86"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=7SG3HZms"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/KRHZUdjTD6g" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2008/11/18/ruby-on-rack-2-rack-builder</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2008-11-17:2794</id>
    <published>2008-11-17T13:08:00Z</published>
    <updated>2008-11-17T13:08:26Z</updated>
    <category term="rack" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/GYSEq873WUI/ruby-on-rack-1" rel="alternate" type="text/html" />
    <title>Ruby on Rack #1 - Hello Rack!</title>
<content type="html">
            &lt;p&gt;Ruby community is coming up with new frameworks almost every week, but in midst of that, &lt;a href="http://rack.rubyforge.org"&gt;Rack&lt;/a&gt; isn’t getting enough attention. Attention that it deserves. And also, the next stable release of &lt;a href="http://rubyonrails.com"&gt;Rails&lt;/a&gt; after 2.2 will have a better public facing interface for taking full advantage of Rack.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://rack.rubyforge.org"&gt;Rack&lt;/a&gt; was initially inspired from pythons’s &lt;a href="http://www.wsgi.org/wsgi"&gt;wsgi&lt;/a&gt; and it quickly became the de-facto web application/server interface in the ruby community, thanks to it’s simplicity and preciseness. You might want to read &lt;a href="http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html"&gt;Introducing Rack&lt;/a&gt; from the creator of rack – &lt;a href="http://chneukirchen.org"&gt;Christian Neukirchen&lt;/a&gt; before reading this post.&lt;/p&gt;


	&lt;h1&gt;What is Rack ?&lt;/h1&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby.  By wrapping &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests and responses in the simplest way possible, it unifies and distills the &lt;span class="caps"&gt;API&lt;/span&gt; for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;- &lt;a href="http://rack.rubyforge.org/doc"&gt;Rack &lt;span class="caps"&gt;API&lt;/span&gt; Docs&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Practically speaking, you can divide “Rack” in two parts :&lt;/p&gt;


	&lt;h4&gt;Rack Specification&lt;/h4&gt;


	&lt;p&gt;Rack specification specifies how exactly a Rack application and the web server should communicate :&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A Rack application is an Ruby object (not a class) that responds to &lt;ins&gt;call&lt;/ins&gt;. It takes exactly one argument, the &lt;strong&gt;environment&lt;/strong&gt; and returns an Array of exactly three values: The &lt;strong&gt;status&lt;/strong&gt;, the &lt;strong&gt;headers&lt;/strong&gt;, and the &lt;strong&gt;body&lt;/strong&gt;.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;- &lt;a href="http://rack.rubyforge.org/doc/files/SPEC.html"&gt;Rack Specification&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;That’s the specification in a nutshell. You can check out the full details &lt;a href="http://rack.rubyforge.org/doc/files/SPEC.html"&gt;here&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Strictly speaking, you don’t need the rack gem in order to write Rack ready applications.&lt;/strong&gt; Just stick to the specification and that’s it.&lt;/p&gt;


	&lt;h4&gt;Rack Gem&lt;/h4&gt;


	&lt;p&gt;Rack gem is a collection of utilities and facilitating classes, to make life easier for anyone developing Rack applications. It includes basic implementations of request, response, cookies &amp; sessions. And a good number of usefult middlewares. In short, install the rack gem. You’re gonna need it :&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ sudo gem install rack&lt;/code&gt;&lt;/pre&gt;

	&lt;h4&gt;To summarize&lt;/h4&gt;


	&lt;ul&gt;
	&lt;li&gt;Rack is a framework to roll your own ruby framework.&lt;/li&gt;
		&lt;li&gt;Rack provides an interface between different web servers and your framework/application. Making it very simple for your framework/application to be compatible with any webserver that supports Rack – Phusion Passenger, Litespeed, Mongrel, Thin, Ebb, Webrick to name a few.&lt;/li&gt;
		&lt;li&gt;Rack cuts your chase. You get request, response, cookies, params &amp; sessions for free.&lt;/li&gt;
		&lt;li&gt;Makes it possible to use multiple frameworks for the same application, provided there is no class collision. &lt;a href="http://m.onkey.org/2008/11/10/rails-meets-sinatra"&gt;Rails and sinatra integration&lt;/a&gt; is a good example of this.&lt;/li&gt;
		&lt;li&gt;Middlewares ! Think of middlewares as Rails’s before_filter/after_filter that are reusable across different rack supported frameworks/applications. For example, you can use the same Anti-spamming rack middleware for your Rails app, Sinatra app and your custom Rack application too!&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h1&gt;Examples&lt;/h1&gt;


	&lt;p&gt;Let’s start with a smallest possible example of a rack application, using mongrel.&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rubygems&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;HelloWorld&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;call&lt;/span&gt;(env)&lt;tt&gt;
&lt;/tt&gt;    [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello Rack!&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run &lt;span class="co"&gt;HelloWorld&lt;/span&gt;.new, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The above code passes an object of &lt;em&gt;HelloWorld&lt;/em&gt; to the mongrel rack handler, and starts the server on port 9292.&lt;/p&gt;


The &lt;em&gt;HelloWorld&lt;/em&gt; object here respects the rack specifications. That is :
	&lt;ol&gt;
	&lt;li&gt;Responds to &lt;em&gt;call()&lt;/em&gt;, which takes one argument – &lt;em&gt;environment&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;call()&lt;/em&gt; returns an Array of [http_status_code, response_headers_hash, body]&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;That’s all ! If you run this script and browse to &lt;a href="http://localhost:9292"&gt;http://localhost:9292&lt;/a&gt;, you’ll see the shiny “Hello Rack!” message.&lt;/p&gt;


	&lt;p&gt;But hey, even a ruby proc responds to &lt;em&gt;call()&lt;/em&gt;. So why not use a proc instead ? Well, no reason not to :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rubygems&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run proc {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello Rack!&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]}, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Another common seen pattern is to use &lt;em&gt;method(:something)&lt;/em&gt;, which returns an object of &lt;a href="http://ruby-doc.org/core/classes/Method.html"&gt;Method class&lt;/a&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rubygems&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;application&lt;/span&gt;(env)&lt;tt&gt;
&lt;/tt&gt;  [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello Rack!&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Mongrel&lt;/span&gt;.run method(&lt;span class="sy"&gt;:application&lt;/span&gt;), &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;9292&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Take that you “Hello World” performance retards. You’re not gonna be able to write a faster ‘Hello World’ ruby application than this.&lt;/p&gt;


	&lt;h1&gt;Rack it up’&lt;/h1&gt;


	&lt;p&gt;As I said earlier, rack gem comes with a bunch of useful stuff to make life easier of a rack application developer. &lt;em&gt;rackup&lt;/em&gt; is one of them.  In the previous examples, I had used the mongrel handler &lt;em&gt;Rack::Handler::Mongrel&lt;/em&gt; directly, and even hard coded the port number. With &lt;em&gt;rackup&lt;/em&gt;, these things become configurable ! But to use rackup, you’ll need to supply it with a &lt;em&gt;rackup&lt;/em&gt; config file. For our above example, the config file will look somewhat like :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# config.ru&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;run &lt;span class="co"&gt;Proc&lt;/span&gt;.new {|env| [&lt;span class="i"&gt;200&lt;/span&gt;, {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello Rack!&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Just a line. By convention, you should use &lt;em&gt;.ru&lt;/em&gt; extension for a rackup config file. Supply it a &lt;em&gt;run RackObject&lt;/em&gt; and you’re ready to go :&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ rackup config.ru&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;By default, rackup will start a server on &lt;a href="http://0.0.0.0:9292"&gt;port 9292&lt;/a&gt;. But you can override that with a -p option to rackup. For more help, &lt;span class="caps"&gt;RTFM&lt;/span&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ rackup --help&lt;/code&gt;&lt;/pre&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=sidQ4Mld"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=sidQ4Mld" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=KA94c6fe"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=KA94c6fe" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=dLcSsCEK"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=lXyDESuj"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/GYSEq873WUI" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2008/11/17/ruby-on-rack-1</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2008-11-16:2849</id>
    <published>2008-11-16T11:37:00Z</published>
    <updated>2008-11-28T15:53:43Z</updated>
    <category term="rails" />
    <category term="sinatra" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/ojFxRPnHdVE/rails-meets-sinatra-2-mix-n-match" rel="alternate" type="text/html" />
    <title>Rails meets Sinatra #2 - Mix n' Match</title>
<content type="html">
            &lt;p&gt;In &lt;a href="http://m.onkey.org/2008/11/10/rails-meets-sinatra"&gt;my previous post&lt;/a&gt;, we saw how to mount a sinatra application at a specific location for a regular application. But using &lt;em&gt;Rack::Cascade&lt;/em&gt;, we can take that solution to a whole new height. That is :&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Put sinatra code in any of your regular Rails controllers.&lt;/li&gt;
		&lt;li&gt;No need to mount at Sinatra at a specific &lt;span class="caps"&gt;URI&lt;/span&gt;.&lt;/li&gt;
		&lt;li&gt;Have Sinatra work for any &lt;span class="caps"&gt;URI&lt;/span&gt;, gracefully fallback to Rails if no Sinatra method matches the path.&lt;/li&gt;
		&lt;li&gt;Use your models/libraries etc. in both Rails and Sinatra.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So your controllers can look like :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;HomeController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  get &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="co"&gt;Item&lt;/span&gt;.count.to_s&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;and even :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SiteController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  get &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/:name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="co"&gt;Site&lt;/span&gt;.find_by_name(params[&lt;span class="sy"&gt;:name&lt;/span&gt;]).html&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;new&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And &lt;em&gt;environment.rb&lt;/em&gt;:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;RAILS_GEM_VERSION&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;2.2.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;unless&lt;/span&gt; &lt;span class="r"&gt;defined?&lt;/span&gt; &lt;span class="co"&gt;RAILS_GEM_VERSION&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="co"&gt;File&lt;/span&gt;.join(&lt;span class="co"&gt;File&lt;/span&gt;.dirname(&lt;span class="pc"&gt;__FILE__&lt;/span&gt;), &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;boot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rails&lt;/span&gt;::&lt;span class="co"&gt;Initializer&lt;/span&gt;.run &lt;span class="r"&gt;do&lt;/span&gt; |config|&lt;tt&gt;
&lt;/tt&gt;  config.gem &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;sinatra&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  config.time_zone = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;UTC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  config.action_controller.session = { &lt;span class="sy"&gt;:session_key&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;_monkey_session&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,  &lt;span class="sy"&gt;:secret&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;whatever&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;set &lt;span class="sy"&gt;:env&lt;/span&gt;, &lt;span class="sy"&gt;:production&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;disable &lt;span class="sy"&gt;:run&lt;/span&gt;, &lt;span class="sy"&gt;:reload&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Remove trailing slash from URIs reaching Sinatra&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;before { request.env[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;PATH_INFO&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;].gsub!(&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="ch"&gt;\/&lt;/span&gt;&lt;span class="k"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="r"&gt;if&lt;/span&gt; request.env[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;PATH_INFO&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;] != &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Checking AR Connections back to the pool&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;after { &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;.clear_active_connections! }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Preload controllers with Sinatra code&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;home_controller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;site_controller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And most important, the rack setup file :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="co"&gt;File&lt;/span&gt;.dirname(&lt;span class="pc"&gt;__FILE__&lt;/span&gt;) + &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/config/environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;thin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;app = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new {&lt;tt&gt;
&lt;/tt&gt;  use &lt;span class="co"&gt;Rails&lt;/span&gt;::&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Static&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  run &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Cascade&lt;/span&gt;.new([&lt;span class="co"&gt;Sinatra&lt;/span&gt;.application, &lt;span class="co"&gt;ActionController&lt;/span&gt;::&lt;span class="co"&gt;Dispatcher&lt;/span&gt;.new])&lt;tt&gt;
&lt;/tt&gt;}.to_app&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Thin&lt;/span&gt;.run app, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;3000&lt;/span&gt;, &lt;span class="sy"&gt;:Host&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And start your server !&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;[lifo@219 monkey]$ ruby racked.rb&lt;/code&gt;&lt;/pre&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=EWNY3snd"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=EWNY3snd" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=LSxVMgzZ"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=LSxVMgzZ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=cYSW3aUW"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=xGP5mrct"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/ojFxRPnHdVE" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2008/11/16/rails-meets-sinatra-2-mix-n-match</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2008-11-10:2799</id>
    <published>2008-11-10T23:58:00Z</published>
    <updated>2008-11-12T20:23:01Z</updated>
    <category term="rails" />
    <category term="sinatra" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/gahUP59sPmI/rails-meets-sinatra" rel="alternate" type="text/html" />
    <title>Rails meets Sinatra</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://m.onkey.org/assets/2008/11/10/clone-dog-bird.jpg" alt="" /&gt;&lt;/p&gt;


	&lt;h2&gt;For real !&lt;/h2&gt;


	&lt;p&gt;It was pleasantly simple to get Rails + Sinatra run in the same process.&lt;/p&gt;


	&lt;p&gt;First of all, put your Sinatra application inside &lt;em&gt;&lt;span class="caps"&gt;RAILS&lt;/span&gt;_ROOT&lt;/em&gt;. My Sinatra app is called &lt;em&gt;tiny&lt;/em&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# RAILS_ROOT/tiny.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;sinatra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;before { request.env[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;PATH_INFO&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;].gsub!(&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="ch"&gt;\/&lt;/span&gt;&lt;span class="k"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;get &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Hello Sinatra!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And then do the rack dance – &lt;em&gt;racked.rb&lt;/em&gt; :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# RAILS_ROOT/racked.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="co"&gt;File&lt;/span&gt;.dirname(&lt;span class="pc"&gt;__FILE__&lt;/span&gt;) + &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/config/environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;thin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Sinatra stuff&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;tiny&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Make sinatra play nice&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;set &lt;span class="sy"&gt;:env&lt;/span&gt;, &lt;span class="sy"&gt;:production&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;disable &lt;span class="sy"&gt;:run&lt;/span&gt;, &lt;span class="sy"&gt;:reload&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;app = &lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Builder&lt;/span&gt;.new {&lt;tt&gt;
&lt;/tt&gt;  use &lt;span class="co"&gt;Rails&lt;/span&gt;::&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Static&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Anything urls starting with /tiny will go to Sinatra&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/tiny&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run &lt;span class="co"&gt;Sinatra&lt;/span&gt;.application&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Rest with Rails&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  map &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run &lt;span class="co"&gt;ActionController&lt;/span&gt;::&lt;span class="co"&gt;Dispatcher&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;}.to_app&lt;tt&gt;
&lt;/tt&gt; &lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Rack&lt;/span&gt;::&lt;span class="co"&gt;Handler&lt;/span&gt;::&lt;span class="co"&gt;Thin&lt;/span&gt;.run app, &lt;span class="sy"&gt;:Port&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;3000&lt;/span&gt;, &lt;span class="sy"&gt;:Host&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Line 25 ensures your Sinatara application is used for all the urls starting from &lt;em&gt;/tiny&lt;/em&gt;. Any url not starting from &lt;em&gt;/tiny&lt;/em&gt; will go to the Rails application.&lt;/p&gt;


	&lt;p&gt;Now start your server :&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ ruby racked.rb&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;If you go to &lt;a href="http://0.0.0.0:3000/tiny"&gt;http://0.0.0.0:3000/tiny&lt;/a&gt;, you’ll be greeted with ‘Hello from sinatra!’. And your Rails application will continue to work as expected for everything else. Voila! There you have the fastest ‘hello world’ Ruby framework embedded with Rails :)&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Please note that Rails’ built in rack adapter isn’t perfect and you might find a glitch or two. All in good time&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE 1&lt;/span&gt;&lt;/strong&gt;: Prettify Sinatra code and remove monkey patches, thanks to the feedback from &lt;a href="http://sinatrarb.heroku.com"&gt;Blake Mizerany&lt;/a&gt;. Also add a before filter to sinatra app for removing trailing slash.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=IzI52kxF"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=IzI52kxF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=Ik9Fg01Y"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=Ik9Fg01Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=UKobf9Dm"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=0BWNYTik"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/gahUP59sPmI" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2008/11/10/rails-meets-sinatra</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2008-11-03:2734</id>
    <published>2008-11-03T13:00:00Z</published>
    <updated>2008-11-03T13:01:42Z</updated>
    <category term="activesupport" />
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/X76C0mAkymA/activesupport-rescuable" rel="alternate" type="text/html" />
    <title>ActiveSupport::Rescuable</title>
<content type="html">
            &lt;p&gt;In &lt;a href="http://weblog.rubyonrails.org/2008/10/24/rails-2-2-rc1-i18n-thread-safety-docs-etag-last-modified"&gt;Rails 2.2&lt;/a&gt;, controller’s &lt;em&gt;rescue_from&lt;/em&gt; has been extracted to &lt;em&gt;ActiveSupport&lt;/em&gt; as &lt;em&gt;ActiveSupport::Rescuable&lt;/em&gt; module. Relevant commits are &lt;a href="http://github.com/rails/rails/commit/964dfc15572d7c10771c81ac3cbfb455dd5e378e"&gt;964dfc&lt;/a&gt; and &lt;a href="http://github.com/rails/rails/commit/259a7a844b53b7d508145cc61fed9e11581e5409"&gt;259a7a&lt;/a&gt;. This allows you to use &lt;em&gt;rescue_from&lt;/em&gt; functionality in class as a cleaner way of handling exceptions.&lt;/p&gt;


	&lt;p&gt;Now you can just include &lt;em&gt;ActiveSupport::Rescuable&lt;/em&gt; in your class and start using &lt;em&gt;rescue_with_handler(exception)&lt;/em&gt; from your rescue blocks :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Armageddon&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;StandardError&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Earth&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class="co"&gt;ActiveSupport&lt;/span&gt;::&lt;span class="co"&gt;Rescuable&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  rescue_from &lt;span class="co"&gt;Armageddon&lt;/span&gt;, &lt;span class="sy"&gt;:with&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:nuke_the_rock&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;life&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    raise &lt;span class="co"&gt;Armageddon&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;rescue&lt;/span&gt; &lt;span class="co"&gt;Exception&lt;/span&gt; =&amp;gt; e&lt;tt&gt;
&lt;/tt&gt;    rescue_with_handler(e)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;nuke_the_rock&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;snafu&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;e = &lt;span class="co"&gt;Earth&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;e.life&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The above code will produce output “snafu”. You can also check &lt;a href="http://github.com/rails/rails/tree/master/activesupport/lib/active_support/rescuable.rb#L27"&gt;code/docs&lt;/a&gt; if you wanna know more.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=yGnFYlsc"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=yGnFYlsc" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=8Bm4bBPT"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=8Bm4bBPT" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=eRb1Je8o"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=9VbwVqdJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/X76C0mAkymA" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2008/11/3/activesupport-rescuable</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2008-10-23:2564</id>
    <published>2008-10-23T23:31:00Z</published>
    <updated>2008-10-24T11:11:36Z</updated>
    <category term="rails" />
    <category term="ruby" />
    <category term="tips" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/psjOQe2rpkk/thread-safety-for-your-rails" rel="alternate" type="text/html" />
    <title>Thread safety for your Rails</title>
<content type="html">
            &lt;p&gt;Rails 2.2 marks the first release of thread safe Rails. But “thread safety” alone, without any context, doesn’t mean shit. When people say Rails is “thread safe” ( or otherwise ), they usually refer to the dispatching process of Rails. Before 2.2, Rails dispatching looked like :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="cv"&gt;@@guard&lt;/span&gt;.synchronize &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  dispatch_unlocked&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And now it looks somewhat like :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;dispatch_unlocked&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Long story short, Rails can now serve multiple requests in more than one ruby threads ( or native threads if you’re on JRuby ) parallelly. Charles Nutter has done a good job of explaining the details &lt;a href="http://blog.headius.com/2008/08/qa-what-thread-safe-rails-means.html"&gt;here&lt;/a&gt;.&lt;/p&gt;


	&lt;h1&gt;Should you give a flying fuck ?&lt;/h1&gt;


	&lt;p&gt;You totally should if :&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;You’re using JRuby&lt;/li&gt;
		&lt;li&gt;You’re bold enough to play around with bleeding edge &lt;a href="http://www.espace.com.eg/neverblock"&gt;Neverblock&lt;/a&gt; stuff&lt;/li&gt;
		&lt;li&gt;Your application has a lot of long running processes, which are not heavy on blocking IO ( this would be rare I imagine )&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You totally should &lt;span class="caps"&gt;NOT&lt;/span&gt; if :&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;You’re using Event based mongrel, thin or any of the event based web server in production. Event based servers don’t use Threads, so it just doesn’t matter.&lt;/li&gt;
		&lt;li&gt;You &lt;span class="caps"&gt;CBA&lt;/span&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You may have heard a bunch of hype about how threads make everything 100x faster, this is far from the truth. Don’t believe everything the hype merchants want to sell you, test your application first and see if it helps.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.koziarski.net"&gt;Koz’s&lt;/a&gt; comments sums it up nicely :&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;I think the more interesting issue to consider is whether your application will benefit from ‘threaded dispatching’ at all.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;blockquote&gt;
		&lt;p&gt;The performance of green threads in ruby is kind of disappointing, as are the number of different options which block the interpreter. IO, regexps, calling most native libraries, etc. Odds are with matz’s ruby you’re infinitely better off using passenger + ruby enterprise edition than ruby threads.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;blockquote&gt;
		&lt;p&gt;JRuby is another matter altogether, and it’s jruby users who should be most excited about this stuff, and the most willing to help us iron out any last bugs.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h1&gt;Prepare your mongrels first&lt;/h1&gt;


	&lt;p&gt;Currently, you’ll need to manually patch Mongrel’s built in Rails handler for testing multithreaded dispatching. I’ve submitted &lt;a href="http://mongrel.rubyforge.org/ticket/48"&gt;a patch to mongrel&lt;/a&gt; and hopefully there’ll be a new gem version of mongrel soon. In the mean time, monkey patch &lt;span class="caps"&gt;FTW&lt;/span&gt;.&lt;/p&gt;


	&lt;h2&gt;How to enable multi threaded dispatching ?&lt;/h2&gt;


	&lt;p&gt;Just put the following lines in your &lt;em&gt;production.rb&lt;/em&gt;&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;config.threadsafe!&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;However, that’s not enough. There are some consequences if you have never made sure to write thread safe code. They are, however, simple to fix. Usually.&lt;/p&gt;


	&lt;h1&gt;Ruby’s require is not atomic&lt;/h1&gt;


	&lt;p&gt;What this means is, if in &lt;strong&gt;Thread A&lt;/strong&gt; you require a file named &lt;em&gt;whatever.rb&lt;/em&gt; in which defines a class called &lt;em&gt;Whatever&lt;/em&gt;, the class &lt;em&gt;Whatever&lt;/em&gt; can be visible from &lt;strong&gt;Thread B&lt;/strong&gt; even before &lt;strong&gt;Thread A&lt;/strong&gt; has finished loading &lt;em&gt;whatever.rb&lt;/em&gt;. And because of this ruby behavior, Rails now preloads everything inside &lt;em&gt;app&lt;/em&gt; directory.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;config.threadsafe!&lt;/em&gt; also disables automatic loading by &lt;em&gt;ActiveSupport::Dependencies&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;ActiveSupport::Dependencies&lt;/em&gt; uses ruby’s &lt;em&gt;const_missing&lt;/em&gt; hook to load files automatically for you, whenever possible. For example, if you have following file inside your application’s &lt;em&gt;lib/&lt;/em&gt; directory :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# hello.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Hello&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;world&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Rails has traditionally saved you the trouble of requring that file manually inside your application. Whenever you access &lt;em&gt;Hello&lt;/em&gt; ( Hello.new for example ) constant for the first time, &lt;em&gt;ActiveSupport::Dependencies&lt;/em&gt; loads &lt;em&gt;hello.rb&lt;/em&gt; for you automatically. Note that this is only possible if the file name matches the class name that it defines.&lt;/p&gt;


	&lt;p&gt;But as this behavior is disabled when you calls &lt;em&gt;config.threadsafe!&lt;/em&gt;, you’ll now need to require the file &lt;em&gt;hello.rb&lt;/em&gt; manually before Rails starts serving the requests ( typically inside &lt;em&gt;environment.rb&lt;/em&gt; or an initializer ).&lt;/p&gt;


	&lt;p&gt;Alternatively, you can just add &lt;em&gt;lib/&lt;/em&gt; directory to eager load paths. The following inside &lt;em&gt;production.rb&lt;/em&gt; will do that :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;config.eager_load_paths &amp;lt;&amp;lt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;/lib&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And that will make Rails preload everything inside &lt;em&gt;lib/&lt;/em&gt; directory.&lt;/p&gt;


	&lt;h1&gt;Don’t mess with class variables&lt;/h1&gt;


	&lt;p&gt;Imagine your controller having a code that does :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;HomeController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="cv"&gt;@@visits&lt;/span&gt; = &lt;span class="i"&gt;0&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="cv"&gt;@@visits&lt;/span&gt; += &lt;span class="i"&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    render &lt;span class="sy"&gt;:text&lt;/span&gt; =&amp;gt; &lt;span class="cv"&gt;@@visits&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This code is not safe if you enable multi threaded dispatching. All your instance methods ( &lt;em&gt;actions&lt;/em&gt; in case of controllers ) should only read global values ( $vars, @@vars, class instance variables ) and never modify them.&lt;/p&gt;


	&lt;p&gt;Here’s a better example which would explains the consequences as well :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;HomeController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  before_filter &lt;span class="sy"&gt;:set_site&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  private&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;set_site&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@site&lt;/span&gt; = &lt;span class="co"&gt;Site&lt;/span&gt;.find_by_subdomain(request.subdomains.first)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="iv"&gt;@site&lt;/span&gt;.layout?&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="pc"&gt;self&lt;/span&gt;.class.layout(&lt;span class="iv"&gt;@site&lt;/span&gt;.layout_name)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="pc"&gt;self&lt;/span&gt;.class.layout(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;default_lay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;What happens here is :&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Before filter &lt;em&gt;set_site&lt;/em&gt; uses subdomain to populate &lt;em&gt;@site&lt;/em&gt; instance variable&lt;/li&gt;
		&lt;li&gt;It also sets the layout to @site.layout_name is not nil&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Imagine your application has two possible subdomains :&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;foo – has a layout called ‘foo_lay’&lt;/li&gt;
		&lt;li&gt;bar – has no layout. Uses default layout ‘default_lay’&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;When you call &lt;em&gt;self.class.layout(value)&lt;/em&gt;, Rails will store the &lt;em&gt;value&lt;/em&gt; inside a class variable &lt;em&gt;@@layout&lt;/em&gt;, which causes a race condition if called from multiple instance methods in different threads. &lt;a href="http://en.wikipedia.org/wiki/Race_condition"&gt;Wikipedia page&lt;/a&gt; will do a better job of explaining what is a &lt;em&gt;race condition&lt;/em&gt; if you have never bothered about it before.&lt;/p&gt;


	&lt;p&gt;Let us assume that two users are accessing the application : UserA and UserB. UserA’s request is served by Thread1 and UserB’s request is served by Thread2. Here, numbers also represent the order in which these events occur :&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Thread1 : UserA visits http://foo.site.com/home&lt;/li&gt;
		&lt;li&gt;Thread1 : HomeController#set_site calls self.class.layout(@site.layout_name)&lt;/li&gt;
		&lt;li&gt;Thread1 : This sets HomeController#@@layout to ‘foo_lay’&lt;/li&gt;
		&lt;li&gt;&lt;span&gt;Thread2 : UserB visits http://bar.site.com/home&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;&lt;span&gt;Thread2 : HomeController#set_site calls self.class.layout(‘default_lay’)&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;&lt;span&gt;Thread2 : This sets HomeController#@@layout to ‘default_lay’&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Thread1 : Request is done executing action code. Time to send back the response to UserA.&lt;/li&gt;
		&lt;li&gt;Thread1 : Rails calls HomeController#render&lt;/li&gt;
		&lt;li&gt;Thread1 : HomeController#render uses the value of HomeController#@@layout to render the final output html&lt;/li&gt;
		&lt;li&gt;Thread1 : As the value of HomeController#@@layout was modified by #6 to ‘default_lay’, #9 will uses ‘default_lay’ even if the expected layout was ‘foo_lay’&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;The thread safe way to write this code is :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;HomeController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  before_filter &lt;span class="sy"&gt;:set_site&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  layout &lt;span class="sy"&gt;:site_layout&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  private&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;set_site&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@site&lt;/span&gt; = &lt;span class="co"&gt;Site&lt;/span&gt;.find_by_subdomain(request.subdomains.first)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;site_layout&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="iv"&gt;@site&lt;/span&gt;.layout?&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="iv"&gt;@site&lt;/span&gt;.layout_name&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;default_lay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;When you use &lt;em&gt;layout :site_layout&lt;/em&gt;, Rails will use the return value of &lt;em&gt;site_layout&lt;/em&gt; &lt;strong&gt;instance method&lt;/strong&gt; to determine the layout, which makes it a thread safe way. Please note that this is not the same as calling &lt;em&gt;layout ‘something’&lt;/em&gt;. If you pass a string to the class method &lt;em&gt;layout&lt;/em&gt;, Rails will use the passed value as the layout.&lt;/p&gt;


	&lt;p&gt;( Example inspired from &lt;a href="http://railscasts.com/episodes/125-dynamic-layouts"&gt;Dynamic Layouts Railscast&lt;/a&gt; )&lt;/p&gt;


	&lt;h1&gt;Getting dirty with Thread.current&lt;/h1&gt;


	&lt;p&gt;if you must, you can always use Thread local variables as the last resort. Ruby provides you with a magical hash &lt;em&gt;Thread.current[]&lt;/em&gt; inside any executing thread, where you can store variables accessible anywhere from inside that specific thread. Really, you can check this &lt;a href="http://ruby-doc.org/core/classes/Thread.html#M000484"&gt;docs&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;The following code :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;threads = []&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;threads &amp;lt;&amp;lt; &lt;span class="co"&gt;Thread&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;Thread&lt;/span&gt;.current[&lt;span class="sy"&gt;:hello&lt;/span&gt;] = &lt;span class="i"&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  sleep &lt;span class="i"&gt;2&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;From T1 : &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;Thread&lt;/span&gt;.current[&lt;span class="sy"&gt;:hello&lt;/span&gt;]&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;threads &amp;lt;&amp;lt; &lt;span class="co"&gt;Thread&lt;/span&gt;.new &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;Thread&lt;/span&gt;.current[&lt;span class="sy"&gt;:hello&lt;/span&gt;] = &lt;span class="i"&gt;10&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;From T2 : &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;Thread&lt;/span&gt;.current[&lt;span class="sy"&gt;:hello&lt;/span&gt;]&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;threads.each {|t| t.join }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;will produce :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;From&lt;/span&gt; &lt;span class="co"&gt;T2&lt;/span&gt; : &lt;span class="i"&gt;10&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;From&lt;/span&gt; &lt;span class="co"&gt;T1&lt;/span&gt; : &lt;span class="i"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;You might have seen this in use in with any &lt;em&gt;current_user&lt;/em&gt; hacks : &lt;a href="http://clearcove.ca/blog/2008/08/recipe-restful-permissions-for-rails"&gt;Here&lt;/a&gt; or &lt;a href="http://www.pluitsolutions.com/2006/08/15/rails-auto-assign-created-by-and-updated-by"&gt;here&lt;/a&gt;. But it’s still a hack.&lt;/p&gt;


	&lt;p&gt;If you’re familiar with Rails source ( of interested in being familiar ), you can find Rails using Thread.current[] at several places : Thread.current[:time_zone] or Thread.current[‘query_cache’]. &lt;span class="caps"&gt;I18&lt;/span&gt; gem uses Thread.current[:locale] to store the value of locale specific to the thread.&lt;/p&gt;


	&lt;p&gt;But as I said earlier, &lt;em&gt;Thread.current&lt;/em&gt; should be used as a last resort only.&lt;/p&gt;


	&lt;h1&gt;Good ol’ Mutex&lt;/h1&gt;


	&lt;p&gt;There is always the big fat mutex which can be slapped around a piece of code that you want to execute exclusively per thread. You should check the &lt;a href="http://en.wikipedia.org/wiki/Mutex"&gt;wikipedia page&lt;/a&gt; if you’re looking for some explanation  :&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;HomeController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="cv"&gt;@@lock&lt;/span&gt; = &lt;span class="co"&gt;Mutex&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="cv"&gt;@@lock&lt;/span&gt;.synchronize &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      thread_unsafe_code&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  private&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;thread_unsafe_code&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="cv"&gt;@@something&lt;/span&gt; == &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      do_hello&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;elsif&lt;/span&gt; &lt;span class="cv"&gt;@@something&lt;/span&gt; == &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      do_world&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="cv"&gt;@@something&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;nothing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This ensures that only one thread can be executing &lt;em&gt;thread_unsafe_code()&lt;/em&gt; method at any given point in time. Other threads will block and wait indefinitely for the executing thread to release the lock acquired by &lt;em&gt;@@lock.synchronize&lt;/em&gt;.&lt;/p&gt;


	&lt;h1&gt;Common concerns&lt;/h1&gt;


	&lt;p&gt;&lt;a href="http://adamhooper.com"&gt;Adam Hooper&lt;/a&gt; raised three valid concerns  :&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;What is the likelihood that there is broken code in the Rails core, despite the word “threadsafe!”? If Java frameworks (engineered in a language which, unlike Ruby, was built from the ground up with threads in mind) can provide premonitions, is it not safe to assume Rails is painfully buggy in this regard?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Chances of thread unsafe code being in Rails are close to none. There have never been anything inherently thread unsafe about Rails codebase. If some people had you think otherwise, you listened to the wrong bunch of people/FUD. We’ve had a list of thread unsafe code inside Rails for a long time, and it was a small list.&lt;/p&gt;


	&lt;p&gt;However, thread safety is like a Random Number Generator – &lt;a href="http://metasploit.com/users/hdm/tools/debian-openssl/pmeo9hcjp7aw9.jpg"&gt;You can never be sure&lt;/a&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;All existing plug-ins are thread-unsafe until proven otherwise, right? (And &lt;span class="caps"&gt;IMO&lt;/span&gt; Rails developers should broadcast this at the top of their voices, because promising thread-safety and relying on other people to provide it is shooting oneself in the foot….)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.jeremymcanally.com"&gt;Jeremy&lt;/a&gt;&lt;/strong&gt; says :  No. They are not. Most, in fact, are probably threadsafe. Your claiming this is a major issue is a fairly good indicator that you don’t actually know the core issues with thread safety in Ruby/Rails.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt; : That’s not true. At least all the plugins that I use, are thread safe. Having said that, you should never use a plugin without getting yourself familiar with it’s code base.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Does anybody think thread-safe Rails will ever be suitable for production use? It’s hard enough to convince a project manager to consider it already, with its current, much, much, much, &lt;span class="caps"&gt;MUCH&lt;/span&gt; simpler model.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Short answer, don’t jump the ship if you can’t be bothered about ensuring your code is thread safe. Always stick to “Simplest thing that works” motto &lt;span class="caps"&gt;IMO&lt;/span&gt;. You could just spend some time researching if running multithreaded Rails is going to benefit your application/business at all or not and evaluate that against the risk/time involved.&lt;/p&gt;


	&lt;p&gt;But that doesn’t make threadsafe Rails unsuitable for production use. It makes your specific application/team unsuitable for using thread-safe Rails in production mode. Multi threaded programming has never been easy. However, if you write good OO code, thread safety usually comes for free.&lt;/p&gt;


&lt;strong&gt;&lt;span class="caps"&gt;UPDATES&lt;/span&gt;&lt;/strong&gt; :
	&lt;ol&gt;
	&lt;li&gt;Added Mutex section.&lt;/li&gt;
		&lt;li&gt;Added ‘Common concerns’&lt;/li&gt;
		&lt;li&gt;Added ‘Should you give a flying fuck ?’&lt;/li&gt;
		&lt;li&gt;Added ‘Prepare your mongrels first’&lt;/li&gt;
	&lt;/ol&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=Kycrt9iu"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=Kycrt9iu" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=ZJ8LzpW1"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=ZJ8LzpW1" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=lBLcAKNw"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=geKAZHTv"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/psjOQe2rpkk" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2008/10/23/thread-safety-for-your-rails</feedburner:origLink></entry>
  <entry xml:base="http://m.onkey.org/">
    <author>
      <name>pratik</name>
    </author>
    <id>tag:m.onkey.org,2008-10-05:2309</id>
    <published>2008-10-05T15:11:00Z</published>
    <updated>2008-10-05T15:12:04Z</updated>
    <category term="rails" />
    <category term="security" />
    <link href="http://feedproxy.google.com/~r/monkeyonrails/~3/LBjHCRJqCag/sanity" rel="alternate" type="text/html" />
    <title>Sanity for free</title>
<content type="html">
            &lt;p&gt;Just an experiment.&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;erb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ActionView::Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;_copy_ivars_from_controller_with_sanity&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    variables = _copy_ivars_from_controller_without_sanity&lt;tt&gt;
&lt;/tt&gt;    variables.each &lt;span class="r"&gt;do&lt;/span&gt; |v|&lt;tt&gt;
&lt;/tt&gt;      ivar = instance_variable_get(v)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;if&lt;/span&gt; ivar.is_a?(&lt;span class="co"&gt;Array&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;        values = ivar.map &lt;span class="r"&gt;do&lt;/span&gt; |subivar|&lt;tt&gt;
&lt;/tt&gt;          subivar.respond_to?(&lt;span class="sy"&gt;:to_sanity&lt;/span&gt;) ? subivar.to_sanity : subivar&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        instance_variable_set(v, values)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;elsif&lt;/span&gt; ivar.respond_to?(&lt;span class="sy"&gt;:to_sanity&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;        instance_variable_set(v, ivar.to_sanity)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  alias_method_chain &lt;span class="sy"&gt;:_copy_ivars_from_controller&lt;/span&gt;, &lt;span class="sy"&gt;:sanity&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;Sanity&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Cleaner&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="co"&gt;Object&lt;/span&gt;.instance_methods.each &lt;span class="r"&gt;do&lt;/span&gt; |m|&lt;tt&gt;
&lt;/tt&gt;      delegate m, &lt;span class="sy"&gt;:to&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:@model&lt;/span&gt; &lt;span class="r"&gt;unless&lt;/span&gt; m =~ &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;^__&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;initialize&lt;/span&gt;(model)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="iv"&gt;@model&lt;/span&gt; = model&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;method_missing&lt;/span&gt;(method_id, *arguments, &amp;amp;block)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="iv"&gt;@model&lt;/span&gt;.class.sanitizable_columns.include?(method_id)&lt;tt&gt;
&lt;/tt&gt;        value = &lt;span class="iv"&gt;@model&lt;/span&gt;.send(method_id)&lt;tt&gt;
&lt;/tt&gt;        arguments.first == &lt;span class="pc"&gt;false&lt;/span&gt; ? value : &lt;span class="co"&gt;ERB&lt;/span&gt;::&lt;span class="co"&gt;Util&lt;/span&gt;.h(value)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="iv"&gt;@model&lt;/span&gt;.send(method_id, *arguments, &amp;amp;block)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;Model&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.included(base)&lt;tt&gt;
&lt;/tt&gt;      base.send &lt;span class="sy"&gt;:include&lt;/span&gt;, &lt;span class="co"&gt;InstanceMethods&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      base.send &lt;span class="sy"&gt;:extend&lt;/span&gt;, &lt;span class="co"&gt;ClassMethods&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;InstanceMethods&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;to_sanity&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="co"&gt;Cleaner&lt;/span&gt;.new(&lt;span class="pc"&gt;self&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;ClassMethods&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;sanitizable_columns&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="iv"&gt;@sanitizable_columns&lt;/span&gt; ||= content_columns.find_all {|c| c.text? }.map(&amp;amp;&lt;span class="sy"&gt;:name&lt;/span&gt;).map(&amp;amp;&lt;span class="sy"&gt;:to_sym&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;.send &lt;span class="sy"&gt;:include&lt;/span&gt;, &lt;span class="co"&gt;Sanity&lt;/span&gt;::&lt;span class="co"&gt;Model&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And then..&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&amp;lt;%= &lt;span class="iv"&gt;@item&lt;/span&gt;.name &lt;span class="c"&gt;# sanitized name %&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;%= &lt;span class="iv"&gt;@item&lt;/span&gt;.name(&lt;span class="pc"&gt;false&lt;/span&gt;) &lt;span class="c"&gt;# unsanitized name  %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;I know, too many methods are missing, edge cases and what not. But hey, it’s just an idea/experiment.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=hSuzEARd"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=hSuzEARd" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=zHdNT0AP"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?i=zHdNT0AP" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=l2tWETWz"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/monkeyonrails?a=aVFxiHXm"&gt;&lt;img src="http://feeds.feedburner.com/~f/monkeyonrails?d=52" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/monkeyonrails/~4/LBjHCRJqCag" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://m.onkey.org/2008/10/5/sanity</feedburner:origLink></entry>
</feed>
