<?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">
  <id>tag:m.onkey.org,2005:/feed/atom</id>
  <link type="text/html" href="http://m.onkey.org" rel="alternate" />
  
  <title>has_many :bugs, :through =&gt; :rails</title>
  <updated>2011-08-28T13:19:13Z</updated>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/monkeyonrails" /><feedburner:info uri="monkeyonrails" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <id>tag:m.onkey.org,2005:Entry/81</id>
    <published>2011-08-29T12:16:38Z</published>
    <updated>2011-08-29T12:16:38Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/N84RZOO4oa0/active-record-batch-processing-in-parallel-processes" rel="alternate" />
    <title>Active Record batch processing in parallel processes</title>
    <content type="html">&lt;p&gt;Active Record provides &lt;tt&gt;find_each&lt;/tt&gt; for batch processing of large number of records. However, when you are dealing with &lt;em&gt;&lt;span class="caps"&gt;REALLY&lt;/span&gt;&lt;/em&gt; larger number of records ( I&amp;#8217;m talking millions here ), &lt;tt&gt;find_each&lt;/tt&gt; can become quite slow.&lt;/p&gt;
&lt;p&gt;One obvious solution is to use something like &lt;tt&gt;Resque&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;User&lt;/span&gt;.find_each {|user| &lt;span class="co"&gt;Resque&lt;/span&gt;.enqueue(&lt;span class="co"&gt;MyJob&lt;/span&gt;, user) }&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But this solution can feel a little &lt;em&gt;heavy&lt;/em&gt; in certain cases. Enter forking!&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="co"&gt;GC&lt;/span&gt;.respond_to?(&lt;span class="sy"&gt;:copy_on_write_friendly=&lt;/span&gt;)
  &lt;span class="co"&gt;GC&lt;/span&gt;.copy_on_write_friendly = &lt;span class="pc"&gt;true&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;

jobs_per_process = &lt;span class="i"&gt;100&lt;/span&gt;
process_count = &lt;span class="i"&gt;10&lt;/span&gt;

&lt;span class="co"&gt;User&lt;/span&gt;.find_in_batches(&lt;span class="sy"&gt;:batch_size&lt;/span&gt; =&amp;gt; jobs_per_process * process_count) &lt;span class="r"&gt;do&lt;/span&gt; |group|
  batches = group.in_groups(process_count)

  batches.each &lt;span class="r"&gt;do&lt;/span&gt; |batch|
    &lt;span class="co"&gt;Process&lt;/span&gt;.fork &lt;span class="r"&gt;do&lt;/span&gt;
      &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;.establish_connection

      &lt;span class="c"&gt;# Do the actual work&lt;/span&gt;
      batch.each {|user| .. }
    &lt;span class="r"&gt;end&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;

  &lt;span class="co"&gt;Process&lt;/span&gt;.waitall
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above code fetches 1000 records from the db, forks 10 processes and processes 100 records in each process, in parallel, before moving on to the next 1000 records. This should be significantly faster than the usual sequential processing.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s advisable to use &lt;a href="http://www.rubyenterpriseedition.com"&gt;&lt;span class="caps"&gt;REE&lt;/span&gt;&lt;/a&gt; for doing something like this when memory usage is a concern.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=N84RZOO4oa0:AkOHqoRsisI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=N84RZOO4oa0:AkOHqoRsisI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=N84RZOO4oa0:AkOHqoRsisI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=N84RZOO4oa0:AkOHqoRsisI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=N84RZOO4oa0:AkOHqoRsisI: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=N84RZOO4oa0:AkOHqoRsisI: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/N84RZOO4oa0" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/active-record-batch-processing-in-parallel-processes</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/77</id>
    <published>2011-07-29T16:45:11Z</published>
    <updated>2011-08-09T10:31:25Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/bnxW-jAOgtE/using-ruby-debug-with-pow" rel="alternate" />
    <title>Using ruby-debug with Pow</title>
    <content type="html">&lt;p&gt;After moving to Sam Stephenson&amp;#8217;s awesome &lt;a href="http://pow.cx"&gt;Pow&lt;/a&gt;, not being able to use &lt;tt&gt;ruby-debug&lt;/tt&gt; was the primary obstacle I had adjusting to my new development environment. But as it turns out, it&amp;#8217;s very simple to use &lt;tt&gt;ruby-debug&lt;/tt&gt; with &lt;tt&gt;Pow&lt;/tt&gt;.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Make sure you have &lt;tt&gt;ruby-debug&lt;/tt&gt; in your &lt;tt&gt;Gemfile&lt;/tt&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;gem &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;ruby-debug19&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="c"&gt;# 'ruby-debug' if using Ruby 1.8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
	&lt;li&gt;Add the following to the bottom of your application&amp;#8217;s &lt;tt&gt;development.rb&lt;/tt&gt; config file:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;unless&lt;/span&gt; &lt;span class="gv"&gt;$rails_rake_task&lt;/span&gt;
  require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;ruby-debug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;

  &lt;span class="co"&gt;Debugger&lt;/span&gt;.settings[&lt;span class="sy"&gt;:autoeval&lt;/span&gt;] = &lt;span class="pc"&gt;true&lt;/span&gt;
  &lt;span class="co"&gt;Debugger&lt;/span&gt;.settings[&lt;span class="sy"&gt;:autolist&lt;/span&gt;] = &lt;span class="i"&gt;1&lt;/span&gt;
  &lt;span class="co"&gt;Debugger&lt;/span&gt;.settings[&lt;span class="sy"&gt;:reload_source_on_change&lt;/span&gt;] = &lt;span class="pc"&gt;true&lt;/span&gt;
  &lt;span class="co"&gt;Debugger&lt;/span&gt;.start_remote
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will start a debugger server.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Restart &lt;tt&gt;Pow&lt;/tt&gt; and connect to your debugger server from a terminal:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;[lifo@null ~]$ rdebug -c
Connected.&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should now see a &lt;tt&gt;ruby-debug&lt;/tt&gt; console whenever the application hits a breapoint.&lt;/p&gt;
&lt;h3&gt;Being unobtrusive&lt;/h3&gt;
&lt;p&gt;If you don&amp;#8217;t want to bother your co-workers with the &lt;tt&gt;ruby-debug&lt;/tt&gt; stuff, you can configure a global &lt;tt&gt;.gitignore&lt;/tt&gt; file and setup &lt;tt&gt;ruby-debug&lt;/tt&gt; from an initializer that&amp;#8217;s ignored via the global &lt;tt&gt;.gitignore&lt;/tt&gt;.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Setup global &lt;tt&gt;.gitignore&lt;/tt&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;$ git config --global core.excludesfile ~/.gitignore
$ echo my_super_secret_ruby_debug_initializer.rb &amp;gt;&amp;gt; ~/.gitignore&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
	&lt;li&gt;Add an initializer for setting up &lt;tt&gt;ruby-debug&lt;/tt&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# config/initializers/my_super_secret_ruby_debug_initializer.rb&lt;/span&gt;
&lt;span class="r"&gt;if&lt;/span&gt; (&lt;span class="co"&gt;Rails&lt;/span&gt;.env.development? || &lt;span class="co"&gt;Rails&lt;/span&gt;.env.test?) &amp;amp;&amp;amp; !&lt;span class="gv"&gt;$rails_rake_task&lt;/span&gt;
  require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;ruby-debug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;

  &lt;span class="co"&gt;Debugger&lt;/span&gt;.settings[&lt;span class="sy"&gt;:autoeval&lt;/span&gt;] = &lt;span class="pc"&gt;true&lt;/span&gt;
  &lt;span class="co"&gt;Debugger&lt;/span&gt;.settings[&lt;span class="sy"&gt;:autolist&lt;/span&gt;] = &lt;span class="i"&gt;1&lt;/span&gt;
  &lt;span class="co"&gt;Debugger&lt;/span&gt;.settings[&lt;span class="sy"&gt;:reload_source_on_change&lt;/span&gt;] = &lt;span class="pc"&gt;true&lt;/span&gt;
  &lt;span class="co"&gt;Debugger&lt;/span&gt;.start_remote
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You&amp;#8217;ll still need to have &lt;tt&gt;ruby-debug&lt;/tt&gt; in &lt;tt&gt;Gemfile&lt;/tt&gt;. But I imagine that&amp;#8217;ll go unnoticed!&lt;/p&gt;
&lt;p&gt;If you are not religiously using &lt;tt&gt;ruby-debug&lt;/tt&gt; already, you are certainly missing out. Here are a few resources that should help you get started:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://railscasts.com/episodes/54-debugging-with-ruby-debug"&gt;Debugging with ruby-debug&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-ruby-debug"&gt;Rails guide on ruby-debug&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://bashdb.sourceforge.net/ruby-debug/home-page.html"&gt;ruby-debug homepage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt; 1&lt;/strong&gt;: Added $rails_rake_task checks to make sure not to start the debugger for rake tasks&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=bnxW-jAOgtE:gCbBZH5TKnU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=bnxW-jAOgtE:gCbBZH5TKnU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=bnxW-jAOgtE:gCbBZH5TKnU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=bnxW-jAOgtE:gCbBZH5TKnU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=bnxW-jAOgtE:gCbBZH5TKnU: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=bnxW-jAOgtE:gCbBZH5TKnU: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/bnxW-jAOgtE" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/using-ruby-debug-with-pow</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/75</id>
    <published>2011-02-13T16:59:58Z</published>
    <updated>2011-08-11T21:09:15Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/Sotcm8P0Dt8/cramp-0-12" rel="alternate" />
    <title>Cramp 0.12</title>
    <content type="html">&lt;h2&gt;Moved to &lt;a href="http://cramp.in"&gt;http://cramp.in&lt;/a&gt;&lt;/h2&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=Sotcm8P0Dt8:0RBTRMSec50:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=Sotcm8P0Dt8:0RBTRMSec50:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=Sotcm8P0Dt8:0RBTRMSec50:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=Sotcm8P0Dt8:0RBTRMSec50:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=Sotcm8P0Dt8:0RBTRMSec50: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=Sotcm8P0Dt8:0RBTRMSec50: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/Sotcm8P0Dt8" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/cramp-0-12</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/74</id>
    <published>2011-01-31T13:34:18Z</published>
    <updated>2011-01-31T13:38:01Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/rd8yee8uEAs/bulk-alter-table-with-rails-3-and-mysql" rel="alternate" />
    <title>Bulk ALTER TABLE with Rails 3 and MySQL</title>
    <content type="html">&lt;p&gt;With &lt;a href="https://github.com/rails/rails/commit/30176f28a41681c7607eed39d03501327869d40c"&gt;this commit&lt;/a&gt;, Rails migrations will support adding/removing/changing multiple columns via a single &lt;em&gt;&lt;span class="caps"&gt;ALTER&lt;/span&gt; &lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/em&gt; statement for MySQL.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s say you need to add 2 new columns to a table and modify data type of another column. Normally, you&amp;#8217;d do something like this from a migration:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;change_table(&lt;span class="sy"&gt;:users&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |t|
  t.string &lt;span class="sy"&gt;:im_handle&lt;/span&gt;
  t.belongs_to &lt;span class="sy"&gt;:company&lt;/span&gt;
  t.change &lt;span class="sy"&gt;:birthdate&lt;/span&gt;, &lt;span class="sy"&gt;:datetime&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above translates to 3 separate &lt;em&gt;&lt;span class="caps"&gt;ALTER&lt;/span&gt; &lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/em&gt; statements:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;ALTER TABLE `users` ADD `im_handle` varchar(255)
ALTER TABLE `users` ADD `company_id` int(11)
ALTER TABLE `users` CHANGE `updated_at` `updated_at` datetime DEFAULT NULL&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now if you read the &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/alter-table.html"&gt;relevant MySQL documentation&lt;/a&gt;, it&amp;#8217;s a little fucked up how &lt;em&gt;&lt;span class="caps"&gt;ALTER&lt;/span&gt; &lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/em&gt; works. But in a nutshell, here&amp;#8217;s what MySQL does.&lt;/p&gt;
&lt;p&gt;1. Write lock the table. So no more &lt;em&gt;&lt;span class="caps"&gt;INSERT&lt;/span&gt;&lt;/em&gt; or &lt;em&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;&lt;/em&gt;.&lt;br /&gt;
2. Make a temporary copy of the table, including all its data.&lt;br /&gt;
3. Do all that alteration on the temporary table.&lt;br /&gt;
4. Make the temporary table new primary. Get rid of the original primary table.&lt;/p&gt;
&lt;p&gt;Whew! Imagine doing this 3 times for a table containing millions of rows. Hint: It&amp;#8217;s not pleasant.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/rails/rails/commit/30176f28a41681c7607eed39d03501327869d40c"&gt;This commit&lt;/a&gt; adds a new &lt;em&gt;:bulk =&amp;gt; true&lt;/em&gt; option to &lt;em&gt;change_table&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;At the time of writing this, only &amp;#8216;mysql&amp;#8217; adapter supports the &lt;em&gt;:bulk&lt;/em&gt; option.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;change_table(&lt;span class="sy"&gt;:users&lt;/span&gt;, &lt;span class="sy"&gt;:bulk&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |t|
  t.string &lt;span class="sy"&gt;:im_handle&lt;/span&gt;
  t.belongs_to &lt;span class="sy"&gt;:company&lt;/span&gt;
  t.change &lt;span class="sy"&gt;:birthdate&lt;/span&gt;, &lt;span class="sy"&gt;:datetime&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;:bulk =&amp;gt; true&lt;/em&gt; makes sure the &lt;em&gt;change_table&lt;/em&gt; runs only 1 &lt;em&gt;&lt;span class="caps"&gt;ALTER&lt;/span&gt; &lt;span class="caps"&gt;TABLE&lt;/span&gt;&lt;/em&gt; statement.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;ALTER TABLE `users` ADD COLUMN `im_handle` varchar(255), ADD COLUMN `company_id` int(11), CHANGE `updated_at` `updated_at` datetime DEFAULT NULL&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When you are dealing with massive tables, &lt;em&gt;:bulk =&amp;gt; true&lt;/em&gt; will not only make your migration run faster, but also make it more atomic.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=rd8yee8uEAs:cson48U7ID8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=rd8yee8uEAs:cson48U7ID8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=rd8yee8uEAs:cson48U7ID8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=rd8yee8uEAs:cson48U7ID8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=rd8yee8uEAs:cson48U7ID8: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=rd8yee8uEAs:cson48U7ID8: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/rd8yee8uEAs" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/bulk-alter-table-with-rails-3-and-mysql</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/73</id>
    <published>2010-12-23T12:36:11Z</published>
    <updated>2010-12-23T12:36:11Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/C4xWvV5vMgk/nested-layouts-in-rails-3" rel="alternate" />
    <title>Nested layouts in Rails 3</title>
    <content type="html">&lt;p&gt;This an update/rewrite of my previous post &lt;a href="http://m.onkey.org/nested-layouts"&gt;nested layouts&lt;/a&gt; &amp;#8211; as that version no longer works with Rails 3.&lt;/p&gt;
&lt;h3&gt;Code&lt;/h3&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;parent_layout&lt;/span&gt;(layout)
  &lt;span class="iv"&gt;@_content_for&lt;/span&gt;[&lt;span class="sy"&gt;:layout&lt;/span&gt;] = &lt;span class="pc"&gt;self&lt;/span&gt;.output_buffer
  &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="idl"&gt;#{&lt;/span&gt;layout&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add the above helper method in your &lt;em&gt;ApplicationHelper&lt;/em&gt; or wherever you see fit.&lt;/p&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;Let&amp;#8217;s say your application has an admin section. And for all the views using &lt;em&gt;admin.html.erb&lt;/em&gt; layout, you want to fetch stylesheets, javascript, footer etc. from the &lt;em&gt;application.html.erb&lt;/em&gt; layout. One way to do this would be to keep the shared code in partials. However, using inheritance style layouts feels more natural to me.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s how you can use &lt;em&gt;application.html.erb&lt;/em&gt; as the layout for the &lt;em&gt;admin.html.erb&lt;/em&gt; layout :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;# layouts/admin.html.erb
&lt;span class="ta"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Admin Panel&lt;span class="ta"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="ta"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="an"&gt;class&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;admin_navigation&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;Home | Posts | Users | Assets&lt;span class="ta"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;%= yield %&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;%= parent_layout 'application' %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Your &lt;em&gt;application.html.erb&lt;/em&gt; layout is just another regular layout that can be used independently.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# layouts/application.html.erb&lt;/span&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;
  &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;
  &amp;lt;body&amp;gt;
    &amp;lt;&lt;span class="s"&gt;&lt;span class="dl"&gt;%=&lt;/span&gt;&lt;span class="k"&gt; yield %&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Using &lt;em&gt;admin.html.erb&lt;/em&gt; layout is now affectively same as using the following layout :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&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;
  &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;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;&lt;span class="co"&gt;Admin&lt;/span&gt; &lt;span class="co"&gt;Panel&lt;/span&gt;&amp;lt;&lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;h1&amp;gt;
    &amp;lt;div class=&amp;quot;admin_navigation&amp;quot;&amp;gt;Home | Posts | Users | Assets&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;div&amp;gt;
    &amp;lt;&lt;span class="s"&gt;&lt;span class="dl"&gt;%=&lt;/span&gt;&lt;span class="k"&gt; yield %&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=C4xWvV5vMgk:xVgVSu1MiCo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=C4xWvV5vMgk:xVgVSu1MiCo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=C4xWvV5vMgk:xVgVSu1MiCo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=C4xWvV5vMgk:xVgVSu1MiCo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=C4xWvV5vMgk:xVgVSu1MiCo: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=C4xWvV5vMgk:xVgVSu1MiCo: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/C4xWvV5vMgk" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/nested-layouts-in-rails-3</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/69</id>
    <published>2010-02-05T12:37:00Z</published>
    <updated>2010-11-17T13:38:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/SqBN-UcAlJE/signed-and-permanent-cookies-in-rails-3" rel="alternate" />
    <title>Signed and Permanent cookies in Rails 3</title>
    <content type="html">&lt;p&gt;David added a very cool feature to Rails recently &amp;#8211; &lt;a href="http://github.com/rails/rails/commit/0200e20f148c96afceeebc4da7b5985643f9f707"&gt;Signed cookies and permanent cookies&lt;/a&gt; This lets you set permanent and/or signed cookies very easily.&lt;/p&gt;
&lt;p&gt;Before this, you&amp;#8217;d have to write :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;cookies[&lt;span class="sy"&gt;:user_preference&lt;/span&gt;] = {
  &lt;span class="sy"&gt;:value&lt;/span&gt; =&amp;gt; &lt;span class="iv"&gt;@current_user&lt;/span&gt;.preferences,
  &lt;span class="sy"&gt;:expires&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;20&lt;/span&gt;.years.from_now.utc
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now just becomes :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;cookies.permanent[&lt;span class="sy"&gt;:user_preference&lt;/span&gt;] = &lt;span class="iv"&gt;@current_user&lt;/span&gt;.preferences&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In case you happen to have seen my &lt;a href="http://m.onkey.org/2009/10/18/railssummit-slides"&gt;Railssummit presentation&lt;/a&gt; I had talked about using &lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/MessageVerifier.html"&gt;ActiveSupport::MessageVerifier&lt;/a&gt; for implementing &amp;#8220;Remember me&amp;#8221; functionality. The above commit makes that a whole lot easier.&lt;/p&gt;
&lt;p&gt;In your model &lt;tt&gt;User.rb&lt;/tt&gt; :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# User.rb&lt;/span&gt;
&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.&lt;span class="fu"&gt;authenticated_with_token&lt;/span&gt;(id, stored_salt)
  u = find_by_id(user_id)
  u &amp;amp;&amp;amp; u.salt == stored_salt ? u : &lt;span class="pc"&gt;nil&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And when the user checks &amp;#8220;Remember me&amp;#8221; box, make sure the following gets run :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;cookies.permanent.signed[&lt;span class="sy"&gt;:remember_me&lt;/span&gt;] = [current_user.id, current_user.salt]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will set a permanent and signed cookie using the secret specified in &lt;tt&gt;ActionController::Base.cookie_verifier_secret&lt;/tt&gt;. If you don&amp;#8217;t have the &lt;tt&gt;cookie_verifier_secret&lt;/tt&gt; defined, you might want to do that in one of the initializers.&lt;/p&gt;
&lt;p&gt;Now when you want to login using the cookie :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;user = &lt;span class="co"&gt;User&lt;/span&gt;.authenticated_with_token(*cookies.signed[&lt;span class="sy"&gt;:remember_me&lt;/span&gt;])&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this specific case, it&amp;#8217;s very important to use the &lt;tt&gt;salt&lt;/tt&gt; in the cookie value. That makes sure the cookie gets invalidated if the user changes his password.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=SqBN-UcAlJE:f_S3M8Fcug4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=SqBN-UcAlJE:f_S3M8Fcug4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=SqBN-UcAlJE:f_S3M8Fcug4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=SqBN-UcAlJE:f_S3M8Fcug4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=SqBN-UcAlJE:f_S3M8Fcug4: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=SqBN-UcAlJE:f_S3M8Fcug4: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/SqBN-UcAlJE" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/signed-and-permanent-cookies-in-rails-3</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/65</id>
    <published>2010-01-22T18:28:00Z</published>
    <updated>2010-11-17T16:41:21Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/8jgF49QDR5k/active-record-query-interface" rel="alternate" />
    <title>Active Record Query Interface 3.0</title>
    <content type="html">&lt;p&gt;I&amp;#8217;ve been working on revamping the Active Record query interface for the last few weeks ( while taking some time off in India from consulting work, before &lt;a href="http://37signals.com/svn/posts/2068-pratik-naik-joins-37signals"&gt;joining 37signals&lt;/a&gt; ), building on top of &lt;a href="http://www.miloops.com"&gt;Emilio&amp;#8217;s&lt;/a&gt; &lt;span class="caps"&gt;GSOC&lt;/span&gt; project of integrating &lt;a href="http://github.com/rails/arel"&gt;ARel&lt;/a&gt; and ActiveRecord. So here&amp;#8217;s an overview of how things are going to work in Rails 3.&lt;/p&gt;
&lt;h2 style="text-align:center;"&gt;What&amp;#8217;s going to be deprecated in Rails 3.1 ?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;These deprecations will be effective in Rails&amp;#8217; 3.1 release ( &lt;span class="caps"&gt;NOT&lt;/span&gt; Rails 3 ) and will be fully removed in Rails 3.2, though there will be an official plugin to continue supporting them. Consider this an advance warning as it involves changing a lot of code.&lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In short, passing &lt;em&gt;options&lt;/em&gt; hash containing &lt;tt&gt;:conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :having, :from, :lock&lt;/tt&gt; to any of the &lt;em&gt;ActiveRecord&lt;/em&gt; provided class methods, is now deprecated.&lt;/p&gt;
&lt;p&gt;Going into details, currently ActiveRecord provides the following finder methods :&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;tt&gt;find(id_or_array_of_ids, options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;find(:first, options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;find(:all, options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;first(options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;all(options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;update_all(updates, conditions, options)&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the following calculation methods :&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;tt&gt;count(column, options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;average(column, options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;minimum(column, options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;maximum(column, options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;sum(column, options)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;calculate(operation, column, options)&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Starting with Rails 3, &lt;strong&gt;supplying any option to the methods above will be deprecated&lt;/strong&gt;. Support for supplying options will be removed from Rails 3.2. Moreover, &lt;tt&gt;find(:first)&lt;/tt&gt; and &lt;tt&gt;find(:all)&lt;/tt&gt; ( without any options ) are also being deprecated in favour of &lt;tt&gt;first&lt;/tt&gt; and &lt;tt&gt;all&lt;/tt&gt;. A tiny little exception here is that &lt;em&gt;count()&lt;/em&gt; will still accept a &lt;tt&gt;:distinct&lt;/tt&gt; option.&lt;/p&gt;
&lt;p&gt;The following shows a few example of the deprecated usages :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;User&lt;/span&gt;.find(&lt;span class="sy"&gt;:all&lt;/span&gt;, &lt;span class="sy"&gt;:limit&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;1&lt;/span&gt;)
&lt;span class="co"&gt;User&lt;/span&gt;.find(&lt;span class="sy"&gt;:all&lt;/span&gt;)
&lt;span class="co"&gt;User&lt;/span&gt;.find(&lt;span class="sy"&gt;:first&lt;/span&gt;)
&lt;span class="co"&gt;User&lt;/span&gt;.first(&lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; {&lt;span class="sy"&gt;:name&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;lifo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;})
&lt;span class="co"&gt;User&lt;/span&gt;.all(&lt;span class="sy"&gt;:joins&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:items&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But the &lt;strong&gt;following is &lt;span class="caps"&gt;NOT&lt;/span&gt; deprecated&lt;/strong&gt; :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;User&lt;/span&gt;.find(&lt;span class="i"&gt;1&lt;/span&gt;)
&lt;span class="co"&gt;User&lt;/span&gt;.find(&lt;span class="i"&gt;1&lt;/span&gt;,&lt;span class="i"&gt;2&lt;/span&gt;,&lt;span class="i"&gt;3&lt;/span&gt;)
&lt;span class="co"&gt;User&lt;/span&gt;.find_by_name(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;lifo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Additionally, supplying options hash to named_scope is also deprecated :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;named_scope &lt;span class="sy"&gt;:red&lt;/span&gt;, &lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; { &lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; }
named_scope &lt;span class="sy"&gt;:red&lt;/span&gt;, lambda {|colour| {&lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; { &lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; colour }} }&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Supplying options hash to &lt;tt&gt;with_scope&lt;/tt&gt;, &lt;tt&gt;with_exclusive_scope&lt;/tt&gt; and &lt;tt&gt;default_scope&lt;/tt&gt; has also been deprecated :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;with_scope(&lt;span class="sy"&gt;:find&lt;/span&gt; =&amp;gt; {&lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; {&lt;span class="sy"&gt;:name&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;lifo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;}) { ... }
with_exclusive_scope(&lt;span class="sy"&gt;:find&lt;/span&gt; =&amp;gt; {&lt;span class="sy"&gt;:limit&lt;/span&gt; =&amp;gt;&lt;span class="i"&gt;1&lt;/span&gt;}) { ... }
default_scope &lt;span class="sy"&gt;:order&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;id DESC&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Dynamic &lt;tt&gt;scoped_by_&lt;/tt&gt; are also going to be deprecated :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;red_items = &lt;span class="co"&gt;Item&lt;/span&gt;.scoped_by_colour(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
red_old_items = &lt;span class="co"&gt;Item&lt;/span&gt;.scoped_by_colour_and_age(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="i"&gt;2&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 style="text-align:center;"&gt;New &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;ActiveRecord in Rails 3 will have the following new finder methods.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;tt&gt;where (:conditions)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;having (:conditions)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;select&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;group&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;order&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;limit&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;offset&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;joins&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;includes (:include)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;lock&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;readonly&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;from&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="footnote" id="fn1"&gt;&lt;a href="#fnr1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; Value in the bracket ( if different ) indicates the previous equivalent finder option.&lt;/p&gt;
&lt;h4&gt;Chainability&lt;/h4&gt;
&lt;p&gt;All of the above methods returns a &lt;em&gt;Relation&lt;/em&gt;. Conceptually, a &lt;em&gt;relation&lt;/em&gt; is very similar to &lt;a href="http://railscasts.com/episodes/112-anonymous-scopes"&gt;an anonymous named scope&lt;/a&gt;. All these methods are defined on the &lt;em&gt;Relation&lt;/em&gt; object as well, making it possible to chain them.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;lifo = &lt;span class="co"&gt;User&lt;/span&gt;.where(&lt;span class="sy"&gt;:name&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;lifo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
new_users = &lt;span class="co"&gt;User&lt;/span&gt;.order(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;users.id DESC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).limit(&lt;span class="i"&gt;20&lt;/span&gt;).includes(&lt;span class="sy"&gt;:items&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You could also apply more finders to the existing relations :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;cars = &lt;span class="co"&gt;Car&lt;/span&gt;.where(&lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
rich_ppls_cars = cars.order(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;cars.price DESC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).limit(&lt;span class="i"&gt;10&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h4&gt;Quacks like a Model&lt;/h4&gt;
&lt;p&gt;A relation quacks just like a model when it comes to the primary &lt;span class="caps"&gt;CRUD&lt;/span&gt; methods. You could call any of the following methods on a relation :&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;tt&gt;new(attributes)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;create(attributes)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;create!(attributes)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;find(id_or_array)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;destroy(id_or_array)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;destroy_all&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;delete(id_or_array)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;delete_all&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;update(ids, updates)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;update_all(updates)&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;exists?&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the following code examples work as expected :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;red_items = &lt;span class="co"&gt;Item&lt;/span&gt;.where(&lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
red_items.find(&lt;span class="i"&gt;1&lt;/span&gt;)
item = red_items.new
item.colour &lt;span class="c"&gt;#=&amp;gt; 'red'&lt;/span&gt;

red_items.exists? &lt;span class="c"&gt;#=&amp;gt; true&lt;/span&gt;
red_items.update_all &lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
red_items.exists? &lt;span class="c"&gt;#=&amp;gt; false&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that calling any of the update or delete/destroy methods would reset the relation, i.e delete the cached records used for optimizing methods like &lt;tt&gt;relation.size&lt;/tt&gt;.&lt;/p&gt;
&lt;h4&gt;Lazy Loading&lt;/h4&gt;
&lt;p&gt;As it might be clear from the examples above, relations are loaded lazily &amp;#8211; i.e you call an enumerable method on them. This is very similar to how associations and named_scopes already work.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;cars = &lt;span class="co"&gt;Car&lt;/span&gt;.where(&lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="c"&gt;# No Query&lt;/span&gt;
cars.each {|c| puts c.name } &lt;span class="c"&gt;# Fires &amp;quot;select * from cars where ...&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This is very useful along side fragment caching. So in your controller action, you could just do :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;index&lt;/span&gt;
  &lt;span class="iv"&gt;@recent_items&lt;/span&gt; = &lt;span class="co"&gt;Item&lt;/span&gt;.limit(&lt;span class="i"&gt;10&lt;/span&gt;).order(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;created_at DESC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And in your view :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;&lt;span class="s"&gt;&lt;span class="dl"&gt;% &lt;/span&gt;&lt;span class="k"&gt;cache('recent_items')&lt;/span&gt;&lt;span class="dl"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="r"&gt;do&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;
  &amp;lt;% @recent_items.each do |item| %&lt;/span&gt;&lt;span class="dl"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    ...
  &amp;lt;&lt;span class="s"&gt;&lt;span class="dl"&gt;% &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="dl"&gt; &lt;/span&gt;&lt;/span&gt;%&amp;gt;
&amp;lt;&lt;span class="s"&gt;&lt;span class="dl"&gt;% &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="dl"&gt; &lt;/span&gt;&lt;/span&gt;%&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In the above example, &lt;tt&gt;&lt;code&gt;recent_items&amp;lt;/tt&amp;gt; are loaded on &amp;lt;tt&amp;gt;&lt;/code&gt;recent_items.each&lt;/tt&gt; call from the view. As the controller doesn&amp;#8217;t actually fire any query, fragment caching becomes more effective without requiring any special work arounds.&lt;/p&gt;
&lt;h4&gt;Force loading &amp;#8211; all, first &amp;amp; last&lt;/h4&gt;
&lt;p&gt;For the times you don&amp;#8217;t need lazy loading, you could just call &lt;em&gt;all&lt;/em&gt; on the relation :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;cars = &lt;span class="co"&gt;Car&lt;/span&gt;.where(&lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).all&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s important to note that &lt;tt&gt;all&lt;/tt&gt; returns an &lt;em&gt;Array&lt;/em&gt; and not a &lt;em&gt;Relation_. This is similar to how things work in Rails 2.3 with &lt;tt&gt;named&lt;/em&gt;scopes&lt;/tt&gt; and &lt;tt&gt;associations&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Similarly, &lt;em&gt;first&lt;/em&gt; and &lt;em&gt;last&lt;/em&gt; will always return an &lt;em&gt;ActiveRecord&lt;/em&gt; object ( or &lt;em&gt;nil&lt;/em&gt; ).&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;cars = &lt;span class="co"&gt;Car&lt;/span&gt;.order(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;created_at ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
oldest_car = cars.first
newest_car = cars.last&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h4&gt;named_scope &amp;#8594; scopes&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Using the method &lt;tt&gt;named_scope&lt;/tt&gt; is deprecated in Rails 3.0. But the only change you&amp;#8217;ll need to make is to remove the &amp;#8220;named_&amp;#8221; part. Supplying finder options hash will be deprecated in Rails 3.1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;tt&gt;named_scope&lt;/tt&gt; have now been renamed to just &lt;tt&gt;&lt;a href="http://github.com/rails/rails/commit/d60bb0a9e4be2ac0a9de9a69041a4ddc2e0cc914"&gt;scope&lt;/a&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;So a definition like :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Item&lt;/span&gt;
  named_scope &lt;span class="sy"&gt;:red&lt;/span&gt;, &lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; { &lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; }
  named_scope &lt;span class="sy"&gt;:since&lt;/span&gt;, lambda {|time| {&lt;span class="sy"&gt;:conditions&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;created_at &amp;gt; ?&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, time] }}
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now becomes :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Item&lt;/span&gt;
  scope &lt;span class="sy"&gt;:red&lt;/span&gt;, &lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; { &lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; }
  scope &lt;span class="sy"&gt;:since&lt;/span&gt;, lambda {|time| {&lt;span class="sy"&gt;:conditions&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;created_at &amp;gt; ?&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, time] }}
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However, as using options hash is going to be deprecated in 3.1, you should write it using the new finder methods :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Item&lt;/span&gt;
  scope &lt;span class="sy"&gt;:red&lt;/span&gt;, where(&lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)
  scope &lt;span class="sy"&gt;:since&lt;/span&gt;, lambda {|time| where(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;created_at &amp;gt; ?&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, time) }
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Internally, named scopes are built on top of &lt;em&gt;Relation&lt;/em&gt;, making it very easy to mix and match them with the finder methods :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;red_items = &lt;span class="co"&gt;Item&lt;/span&gt;.red
available_red_items = red_items.where(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;quantity &amp;gt; ?&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="i"&gt;0&lt;/span&gt;)
old_red_items = &lt;span class="co"&gt;Item&lt;/span&gt;.red.since(&lt;span class="i"&gt;10&lt;/span&gt;.days.ago)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h4&gt;Model.scoped&lt;/h4&gt;
&lt;p&gt;If you want to build a complex relation/query, starting with a blank relation, &lt;em&gt;Model.scoped&lt;/em&gt; is what you would use.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;cars = &lt;span class="co"&gt;Car&lt;/span&gt;.scoped
rich_ppls_cars = cars.order(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;cars.price DESC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).limit(&lt;span class="i"&gt;10&lt;/span&gt;)
white_cars = cars.where(&lt;span class="sy"&gt;:colour&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Speaking of internals, &lt;em&gt;ActiveRecord::Base&lt;/em&gt; has the following delegations :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;delegate &lt;span class="sy"&gt;:find&lt;/span&gt;, &lt;span class="sy"&gt;:first&lt;/span&gt;, &lt;span class="sy"&gt;:last&lt;/span&gt;, &lt;span class="sy"&gt;:all&lt;/span&gt;, &lt;span class="sy"&gt;:destroy&lt;/span&gt;, &lt;span class="sy"&gt;:destroy_all&lt;/span&gt;, &lt;span class="sy"&gt;:exists?&lt;/span&gt;, &lt;span class="sy"&gt;:delete&lt;/span&gt;, &lt;span class="sy"&gt;:delete_all&lt;/span&gt;, &lt;span class="sy"&gt;:update&lt;/span&gt;, &lt;span class="sy"&gt;:update_all&lt;/span&gt;, &lt;span class="sy"&gt;:to&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:scoped&lt;/span&gt;
delegate &lt;span class="sy"&gt;:select&lt;/span&gt;, &lt;span class="sy"&gt;:group&lt;/span&gt;, &lt;span class="sy"&gt;:order&lt;/span&gt;, &lt;span class="sy"&gt;:limit&lt;/span&gt;, &lt;span class="sy"&gt;:joins&lt;/span&gt;, &lt;span class="sy"&gt;:where&lt;/span&gt;, &lt;span class="sy"&gt;:preload&lt;/span&gt;, &lt;span class="sy"&gt;:eager_load&lt;/span&gt;, &lt;span class="sy"&gt;:includes&lt;/span&gt;, &lt;span class="sy"&gt;:from&lt;/span&gt;, &lt;span class="sy"&gt;:lock&lt;/span&gt;, &lt;span class="sy"&gt;:readonly&lt;/span&gt;, &lt;span class="sy"&gt;:having&lt;/span&gt;, &lt;span class="sy"&gt;:to&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:scoped&lt;/span&gt;
delegate &lt;span class="sy"&gt;:count&lt;/span&gt;, &lt;span class="sy"&gt;:average&lt;/span&gt;, &lt;span class="sy"&gt;:minimum&lt;/span&gt;, &lt;span class="sy"&gt;:maximum&lt;/span&gt;, &lt;span class="sy"&gt;:sum&lt;/span&gt;, &lt;span class="sy"&gt;:calculate&lt;/span&gt;, &lt;span class="sy"&gt;:to&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:scoped&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above might give you a better insight on how ActiveRecord is doing things internally. Additionally, dynamic finder methods &lt;tt&gt;find_by_name&lt;/tt&gt;, &lt;tt&gt;find_all_by_name_and_colour&lt;/tt&gt; etc. are also delegated to &lt;em&gt;Relation&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;with_scope and with_exclusive_scope&lt;/h4&gt;
&lt;p&gt;&lt;tt&gt;with_scope&lt;/tt&gt; and &lt;tt&gt;with_exclusive_scope&lt;/tt&gt; are now implemented on top of &lt;em&gt;Relation&lt;/em&gt; as well. Making it possible to use any relation with them :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;with_scope(where(&lt;span class="sy"&gt;:name&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;lifo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)) &lt;span class="r"&gt;do&lt;/span&gt;
  ...
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Or even use a named scope :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;with_exclusive_scope(&lt;span class="co"&gt;Item&lt;/span&gt;.red) &lt;span class="r"&gt;do&lt;/span&gt;
  ...
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;#8217;s all. Please open a &lt;a href="https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/overview"&gt;lighthouse ticket&lt;/a&gt; if you find a bug or have a patch for an improvement!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt; 1&lt;/strong&gt; : Added information about deprecating &lt;tt&gt;scoped_by_&lt;/tt&gt; dynamic methods.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt; 2&lt;/strong&gt; : Added information about deprecating &lt;tt&gt;default_scope&lt;/tt&gt; with finder options.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=8jgF49QDR5k:rr0X4VTJxnE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=8jgF49QDR5k:rr0X4VTJxnE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=8jgF49QDR5k:rr0X4VTJxnE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=8jgF49QDR5k:rr0X4VTJxnE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=8jgF49QDR5k:rr0X4VTJxnE: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=8jgF49QDR5k:rr0X4VTJxnE: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/8jgF49QDR5k" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/active-record-query-interface</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/67</id>
    <published>2010-01-15T18:42:00Z</published>
    <updated>2011-08-11T21:08:47Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/nX02tU5-mos/websockets-made-easy-with-cramp" rel="alternate" />
    <title>Websockets made easy with Cramp</title>
    <content type="html">&lt;h2&gt;Moved to &lt;a href="http://cramp.in"&gt;http://cramp.in&lt;/a&gt;&lt;/h2&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=nX02tU5-mos:jgSbQOc5mjE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=nX02tU5-mos:jgSbQOc5mjE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=nX02tU5-mos:jgSbQOc5mjE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=nX02tU5-mos:jgSbQOc5mjE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=nX02tU5-mos:jgSbQOc5mjE: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=nX02tU5-mos:jgSbQOc5mjE: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/nX02tU5-mos" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/websockets-made-easy-with-cramp</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/66</id>
    <published>2010-01-07T14:17:00Z</published>
    <updated>2011-08-11T21:08:52Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/l3lp79kBMHk/introducing-cramp" rel="alternate" />
    <title>Introducing Cramp</title>
    <content type="html">&lt;h2&gt;Moved to &lt;a href="http://cramp.in"&gt;http://cramp.in&lt;/a&gt;&lt;/h2&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=l3lp79kBMHk:7aXZIBxAK2Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=l3lp79kBMHk:7aXZIBxAK2Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=l3lp79kBMHk:7aXZIBxAK2Q:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=l3lp79kBMHk:7aXZIBxAK2Q:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=l3lp79kBMHk:7aXZIBxAK2Q: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=l3lp79kBMHk:7aXZIBxAK2Q: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/l3lp79kBMHk" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/introducing-cramp</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/64</id>
    <published>2009-10-18T18:47:00Z</published>
    <updated>2010-11-17T13:38:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/76s4kjgUo8s/railssummit-slides" rel="alternate" />
    <title>Railssummit Slides</title>
    <content type="html">&lt;p&gt;Here are the slides of my presentation at &lt;a href="http://www.railssummit.com.br/en"&gt;Railssummit 2009&lt;/a&gt;. Huge thanks to Locaweb and &lt;a href="http://www.akitaonrails.com"&gt;Fabio Akita&lt;/a&gt; for organizing the conference and having me there.&lt;/p&gt;
&lt;p&gt;My talk was about Rails focused tips/tricks.&lt;/p&gt;
&lt;div style="width:425px;text-align:left" id="__ss_2266628"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/pratiknaik/lessons-learnt-in-2009" title="Lessons Learnt in 2009"&gt;Lessons Learnt in 2009&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=lessonslearnt-091018133732-phpapp02&amp;rel=0&amp;stripped_title=lessons-learnt-in-2009" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=lessonslearnt-091018133732-phpapp02&amp;rel=0&amp;stripped_title=lessons-learnt-in-2009" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/pratiknaik"&gt;pratiknaik&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Or you can download the pdf from &lt;a href="http://m.onkey.org/lessons_learnt_2009.pdf"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=76s4kjgUo8s:d37Pvm-ai9Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=76s4kjgUo8s:d37Pvm-ai9Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=76s4kjgUo8s:d37Pvm-ai9Q:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=76s4kjgUo8s:d37Pvm-ai9Q:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=76s4kjgUo8s:d37Pvm-ai9Q: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=76s4kjgUo8s:d37Pvm-ai9Q: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/76s4kjgUo8s" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/railssummit-slides</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/63</id>
    <published>2009-09-20T17:36:00Z</published>
    <updated>2010-11-17T13:38:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/LfXqBrBY6bA/make-your-shoulda-tests-faster-with-fast_context" rel="alternate" />
    <title>Make your shoulda tests faster with fast_context</title>
    <content type="html">&lt;p&gt;I&amp;#8217;ve been using Shoulda for a while. And for my current project, I decided to go fixtureless with Shoulda + Factory Girl. All good, except one problem. Slow as fuck tests. So here&amp;#8217;s &lt;a href="http://github.com/lifo/fast_context"&gt;fast_context&lt;/a&gt; as a solution for it. fast_context compiles all the &amp;#8217;should&amp;#8217;s within a context into a single test.&lt;/p&gt;
&lt;p&gt;For example :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;UsersControllerTest&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActionController&lt;/span&gt;::&lt;span class="co"&gt;TestCase&lt;/span&gt;
  fast_context &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;#new&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;
    setup &lt;span class="r"&gt;do&lt;/span&gt;
      &lt;span class="iv"&gt;@user&lt;/span&gt; = Factory(&lt;span class="sy"&gt;:user&lt;/span&gt;)
      get &lt;span class="sy"&gt;:new&lt;/span&gt;
    &lt;span class="r"&gt;end&lt;/span&gt;

    should_render_template &lt;span class="sy"&gt;:new&lt;/span&gt;
    should_render_with_layout &lt;span class="sy"&gt;:users&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will be compiled into something like :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;UsersControllerTest&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActionController&lt;/span&gt;::&lt;span class="co"&gt;TestCase&lt;/span&gt;
  test &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;test: #new should run_fast&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="iv"&gt;@user&lt;/span&gt; = Factory(&lt;span class="sy"&gt;:user&lt;/span&gt;)
    get &lt;span class="sy"&gt;:new&lt;/span&gt;
    should_render_template &lt;span class="sy"&gt;:new&lt;/span&gt;
    should_render_with_layout &lt;span class="sy"&gt;:users&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As your setup method just once per fast_context, the tests run much faster.&lt;/p&gt;
&lt;p&gt;To install :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;script/plugin install git&lt;span class="sy"&gt;:/&lt;/span&gt;/github.com/lifo/fast_context.git&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This was a result of a short time of hacking. So there may be bugs. Please comment here if you run into any issues.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=LfXqBrBY6bA:YbfZp_xdJQ8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=LfXqBrBY6bA:YbfZp_xdJQ8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=LfXqBrBY6bA:YbfZp_xdJQ8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=LfXqBrBY6bA:YbfZp_xdJQ8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=LfXqBrBY6bA:YbfZp_xdJQ8: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=LfXqBrBY6bA:YbfZp_xdJQ8: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/LfXqBrBY6bA" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/make-your-shoulda-tests-faster-with-fast_context</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/62</id>
    <published>2009-08-07T14:24:00Z</published>
    <updated>2010-11-17T13:38:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/hSI81eoxttY/save-save" rel="alternate" />
    <title>save! &gt; save</title>
    <content type="html">&lt;p&gt;Thoughtbot folks have a great article on not expecting exceptions &amp;#8211; &lt;a href="http://giantrobots.thoughtbot.com/2007/9/26/active-record-programming-with-exceptions"&gt;save bang your head, active record will drive you mad&lt;/a&gt;. I&amp;#8217;ll admit, just like the poster, I used to use &lt;em&gt;save!&lt;/em&gt; in controllers to &lt;em&gt;&lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/em&gt; my code. And have a global &lt;i&gt;rescue_from&lt;/i&gt; in &lt;em&gt;application.rb&lt;/em&gt;. But over the time, I changed the camp and now I&amp;#8217;m fully in that &lt;i&gt;&amp;#8220;Don&amp;#8217;t expect expectations&amp;#8221;&lt;/i&gt; camp. Some things are more important that &lt;em&gt;DRYing&lt;/em&gt; 3 lines of code.&lt;/p&gt;
&lt;p&gt;But I&amp;#8217;d want to take this a step further. &lt;strong&gt;When you&amp;#8217;re not expecting something to fail, always use the methods that raise exceptions on failure.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So I strongly disagree with the poster on this :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I think ActiveRecord::Base#save! and ActiveRecord::Base.update_attributes! should be pulled from the public &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I would advocate just the opposite for certain cases. In many of the code reviews we&amp;#8217;ve done via &lt;a href="http://actionrails.com/services.html"&gt;ActionRails&lt;/a&gt;, the following pattern was seen in many of the models :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;do_something&lt;/span&gt;
  &lt;span class="pc"&gt;self&lt;/span&gt;.foo = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
  save
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;create_items&lt;/span&gt;
  names.each {|n| &lt;span class="pc"&gt;self&lt;/span&gt;.items.create &lt;span class="sy"&gt;:name&lt;/span&gt; =&amp;gt; n }
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In the snippets above, it&amp;#8217;s not checking for cases where the &lt;em&gt;save&lt;/em&gt; fails. And for good reasons that they&amp;#8217;re not likely to fail as code is changing some very minor. But in these scenarios, a failure would be an unexpected situation. Hence you should always use &lt;em&gt;save!&lt;/em&gt; or &lt;em&gt;create!&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;There could be easily be any unexpected reasons the above &lt;em&gt;save&lt;/em&gt; could fail. And using &lt;em&gt;save!&lt;/em&gt; protects you from those situations and help catch those minor programming mistakes early, which otherwise could prove to be very costly in terms of time/efforts. So the above code should really be :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;do_something&lt;/span&gt;
  &lt;span class="pc"&gt;self&lt;/span&gt;.foo = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
  save!
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;create_items&lt;/span&gt;
  names.each {|n| &lt;span class="pc"&gt;self&lt;/span&gt;.items.create! &lt;span class="sy"&gt;:name&lt;/span&gt; =&amp;gt; n }
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However, if you&amp;#8217;re using exceptions for flow control, this practise won&amp;#8217;t always help you :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;create&lt;/span&gt;
  &lt;span class="iv"&gt;@user&lt;/span&gt; = &lt;span class="co"&gt;User&lt;/span&gt;.create! params[&lt;span class="sy"&gt;:user&lt;/span&gt;]
  redirect_to &lt;span class="iv"&gt;@user&lt;/span&gt;
&lt;span class="r"&gt;rescue&lt;/span&gt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;RecordNotSaved&lt;/span&gt;
  flash[&lt;span class="sy"&gt;:notice&lt;/span&gt;] = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Unable to create user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
  render &lt;span class="sy"&gt;:new&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As this catches the exception &lt;em&gt;ActiveRecord::RecordNotSaved&lt;/em&gt;, unexpected &lt;em&gt;save!&lt;/em&gt; failures from your model methods/callbacks will get caught too. And hide the real error.&lt;/p&gt;
&lt;p&gt;Moral of the story :&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Don&amp;#8217;t expect exceptions&lt;/li&gt;
	&lt;li&gt;Use methods throwing exceptions when you&amp;#8217;re not expecting a failure. For example, everywhere you&amp;#8217;re not checking if &lt;em&gt;save&lt;/em&gt; or &lt;em&gt;create&lt;/em&gt; fails when working with &lt;em&gt;Active Record&lt;/em&gt; objects, always use &lt;em&gt;save!&lt;/em&gt; and &lt;em&gt;create!&lt;/em&gt; instead.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=hSI81eoxttY:Z2cTHhlNZlg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=hSI81eoxttY:Z2cTHhlNZlg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=hSI81eoxttY:Z2cTHhlNZlg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=hSI81eoxttY:Z2cTHhlNZlg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=hSI81eoxttY:Z2cTHhlNZlg: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=hSI81eoxttY:Z2cTHhlNZlg: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/hSI81eoxttY" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/save-save</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/61</id>
    <published>2009-08-06T12:16:00Z</published>
    <updated>2010-11-17T13:38:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/ft04wy48Y7k/use-index-with-active-record-finders" rel="alternate" />
    <title>USE INDEX with Active Record finders</title>
    <content type="html">&lt;p&gt;MySQL doesn&amp;#8217;t always pick the right index for your queries. Hence, sometimes you must tell it which index to use. Consider the example :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;Activity&lt;/span&gt;.all(&lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; [&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;created_at &amp;gt;= ? AND country_id = ?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="i"&gt;10&lt;/span&gt;.days.ago, &lt;span class="i"&gt;79&lt;/span&gt;])&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Running &lt;em&gt;&lt;span class="caps"&gt;EXPLAIN&lt;/span&gt;&lt;/em&gt; on the above query :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;EXPLAIN SELECT * FROM `activities` WHERE (created_at &amp;gt;= '2009-07-27 12:58:44' AND country_id = 79);

Possible keys : index_activities_on_created_at,index_activities_on_created_at_and_country_id
Using the key : index_activities_on_created_at&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As you can see, even though the table has index on both the fields involved in the query &amp;#8211; &lt;i&gt;index_activities_on_created_at_and_country_id&lt;/i&gt;, MySQL still uses &lt;i&gt;index_activities_on_created_at&lt;/i&gt;. You can explicitly ask MySQL to use the index you want by supplying &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/index-hints.html"&gt;&lt;span class="caps"&gt;USE&lt;/span&gt; &lt;span class="caps"&gt;INDEX&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;SELECT&lt;/span&gt; * &lt;span class="r"&gt;FROM&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;`&lt;/span&gt;&lt;span class="k"&gt;activities&lt;/span&gt;&lt;span class="dl"&gt;`&lt;/span&gt;&lt;/span&gt; USE &lt;span class="r"&gt;INDEX&lt;/span&gt;(index_activities_on_created_at_and_country_id) 
  &lt;span class="r"&gt;WHERE&lt;/span&gt; (created_at &amp;gt;= &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;2009-07-27 12:58:44&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;AND&lt;/span&gt; country_id = &lt;span class="i"&gt;79&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Active Record does not have any finder option to specify the index hint. Hence the solution is to exploit the &lt;em&gt;:from&lt;/em&gt; option :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;from = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;quoted_table_name&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; USE INDEX(index_activities_on_created_at_and_country_id)&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="co"&gt;Activity&lt;/span&gt;.all(&lt;span class="sy"&gt;:from&lt;/span&gt; =&amp;gt; from, 
             &lt;span class="sy"&gt;:conditions&lt;/span&gt; =&amp;gt; [&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;created_at &amp;gt;= ? AND country_id = ?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="i"&gt;10&lt;/span&gt;.days.ago, &lt;span class="i"&gt;79&lt;/span&gt;])&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=ft04wy48Y7k:CracrwKulpM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=ft04wy48Y7k:CracrwKulpM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=ft04wy48Y7k:CracrwKulpM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=ft04wy48Y7k:CracrwKulpM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=ft04wy48Y7k:CracrwKulpM: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=ft04wy48Y7k:CracrwKulpM: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/ft04wy48Y7k" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/use-index-with-active-record-finders</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/60</id>
    <published>2009-08-05T14:19:00Z</published>
    <updated>2010-11-17T13:38:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/oQDzlNRYND0/ruby-i-don-t-like-3-object-freeze" rel="alternate" />
    <title>Ruby I don't like #3 - Object#freeze</title>
    <content type="html">&lt;p&gt;&lt;a href="http://www.ruby-doc.org/core/classes/Object.html#M000356"&gt;Object#freeze&lt;/a&gt; annoys me. Not a lot, but enough to bitch blog about it. So, &lt;em&gt;freeze&lt;/em&gt; lets you make sure no one else modifies your precious little object :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;gt;&amp;gt; a = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&amp;gt;&amp;gt; a.freeze
&amp;gt;&amp;gt; a &amp;lt;&amp;lt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;wtf&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="co"&gt;TypeError&lt;/span&gt;: can&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;t modify frozen string
        from (irb):23:in `&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
        from (irb):&lt;span class="i"&gt;23&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However, &lt;strong&gt;freeze does not protect the variable. It only protects the value.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;gt;&amp;gt; a = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&amp;gt;&amp;gt; a.freeze
&amp;gt;&amp;gt; a += &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;wtf&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;hellowtf&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The weird behaviour is even more visible when you&amp;#8217;re dealing with arrays :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;gt;&amp;gt; x = [&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hello&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;freedom&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]
&amp;gt;&amp;gt; x.freeze
&amp;gt;&amp;gt; x &amp;lt;&amp;lt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="co"&gt;TypeError&lt;/span&gt;: can&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;t modify frozen array
        from (irb):6:in `&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
        from (irb):&lt;span class="i"&gt;6&lt;/span&gt;
&amp;gt;&amp;gt; x[&lt;span class="i"&gt;0&lt;/span&gt;] &amp;lt;&amp;lt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;wtf&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&amp;gt;&amp;gt; x
=&amp;gt; [&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hellowtf&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;freedom&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s even weird with hashes :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;gt;&amp;gt; a = {&lt;span class="sy"&gt;:x&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;1&lt;/span&gt;}
&amp;gt;&amp;gt; a.freeze
&amp;gt;&amp;gt; a[&lt;span class="sy"&gt;:x&lt;/span&gt;] = &lt;span class="i"&gt;2&lt;/span&gt;
&lt;span class="co"&gt;TypeError&lt;/span&gt;: can&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;t modify frozen hash
        from (irb):11:in `[]=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
        from (irb):&lt;span class="i"&gt;11&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However, above are not really the primary reasons I don&amp;#8217;t like &lt;em&gt;freeze&lt;/em&gt;. It&amp;#8217;s the fact that you cannot unfreeze an object without using something like &lt;a href="http://eigenclass.org/hiki/evil.rb+dl+and+unfreeze"&gt;evil.rb&lt;/a&gt;. And this goes against a lot of things Ruby stands for in my book. Ruby is never about defensive programming. Even where it tries to save you from yourself, there are always proper ways you can overcome the restriction. For example, &lt;em&gt;private&lt;/em&gt; methods and &lt;em&gt;send&lt;/em&gt;. If you want to restrict programmers, Ruby is not for you. Use Java/Python/whatever. Not Ruby. Ruby is not meant for preventing idiots from shooting their leg.&lt;/p&gt;
&lt;p&gt;Taking a real example :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;ActiveSupport&lt;/span&gt;
  &lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;Testing&lt;/span&gt;
    &lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;Performance&lt;/span&gt;
      &lt;span class="co"&gt;DEFAULTS&lt;/span&gt; =
        &lt;span class="r"&gt;if&lt;/span&gt; benchmark = &lt;span class="pc"&gt;ARGV&lt;/span&gt;.include?(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;--benchmark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)  &lt;span class="c"&gt;# HAX for rake test&lt;/span&gt;
          { &lt;span class="sy"&gt;:benchmark&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;true&lt;/span&gt;,
            &lt;span class="sy"&gt;:runs&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;4&lt;/span&gt;,
            &lt;span class="sy"&gt;:metrics&lt;/span&gt; =&amp;gt; [&lt;span class="sy"&gt;:process_time&lt;/span&gt;, &lt;span class="sy"&gt;:memory&lt;/span&gt;, &lt;span class="sy"&gt;:objects&lt;/span&gt;, &lt;span class="sy"&gt;:gc_runs&lt;/span&gt;, &lt;span class="sy"&gt;:gc_time&lt;/span&gt;],
            &lt;span class="sy"&gt;:output&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;tmp/performance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; }
        &lt;span class="r"&gt;else&lt;/span&gt;
          { &lt;span class="sy"&gt;:benchmark&lt;/span&gt; =&amp;gt; &lt;span class="pc"&gt;false&lt;/span&gt;,
            &lt;span class="sy"&gt;:runs&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;1&lt;/span&gt;,
            &lt;span class="sy"&gt;:min_percent&lt;/span&gt; =&amp;gt; &lt;span class="fl"&gt;0.01&lt;/span&gt;,
            &lt;span class="sy"&gt;:metrics&lt;/span&gt; =&amp;gt; [&lt;span class="sy"&gt;:process_time&lt;/span&gt;, &lt;span class="sy"&gt;:memory&lt;/span&gt;, &lt;span class="sy"&gt;:objects&lt;/span&gt;],
            &lt;span class="sy"&gt;:formats&lt;/span&gt; =&amp;gt; [&lt;span class="sy"&gt;:flat&lt;/span&gt;, &lt;span class="sy"&gt;:graph_html&lt;/span&gt;, &lt;span class="sy"&gt;:call_tree&lt;/span&gt;],
            &lt;span class="sy"&gt;:output&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;tmp/performance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; }
        &lt;span class="r"&gt;end&lt;/span&gt;.freeze&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;#8217;s a code from Rails performance tests. As you can see, it defines a hash with config variables based on benchmark or profile mode. And then freezes the hash. Assuming you&amp;#8217;re benchmarking, &lt;em&gt;&lt;span class="caps"&gt;DEFAULTS&lt;/span&gt;[:runs]&lt;/em&gt; determines how many times Rails should run the test in a loop :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;DEFAULTS&lt;/span&gt;[&lt;span class="sy"&gt;:runs&lt;/span&gt;].times { run_test_with_benchmarking &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;whatever test&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now many times when I&amp;#8217;m benchmarking and want to increase the number of times a test is ran, I just want to do something like :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SpeedTest&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActionController&lt;/span&gt;::&lt;span class="co"&gt;PerformanceTest&lt;/span&gt;
  &lt;span class="co"&gt;DEFAULTS&lt;/span&gt;[&lt;span class="sy"&gt;:runs&lt;/span&gt;] = &lt;span class="i"&gt;1000&lt;/span&gt;

  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;test_some_method&lt;/span&gt;
    &lt;span class="co"&gt;Model&lt;/span&gt;.some_method
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However, that&amp;#8217;s not possible thanks to the &lt;em&gt;freeze&lt;/em&gt;. I do know that changing &lt;em&gt;&lt;span class="caps"&gt;DEFAULTS&lt;/span&gt;[:runs]&lt;/em&gt; is not a public &lt;span class="caps"&gt;API&lt;/span&gt; yada yada yada. But it&amp;#8217;s Ruby and I&amp;#8217;ll change whatever the fuck I want to. I can understand certain cases where people use &lt;em&gt;freeze&lt;/em&gt; to prevent silly errors. That&amp;#8217;s probably &lt;em&gt;OK&lt;/em&gt; to a certain extent. But remember, if you design your software for idiots, only idiots will use it.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=oQDzlNRYND0:4emYf_8fRTY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=oQDzlNRYND0:4emYf_8fRTY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=oQDzlNRYND0:4emYf_8fRTY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=oQDzlNRYND0:4emYf_8fRTY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=oQDzlNRYND0:4emYf_8fRTY: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=oQDzlNRYND0:4emYf_8fRTY: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/oQDzlNRYND0" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/ruby-i-don-t-like-3-object-freeze</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/59</id>
    <published>2009-08-04T17:28:00Z</published>
    <updated>2010-11-17T13:38:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/-M-CGLeDnnE/ruby-i-don-t-like-2-catch-wtf-throw-wtf" rel="alternate" />
    <title>Ruby I don't like #2 - catch(:wtf) { throw :wtf }</title>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;The 1960s and 1970s saw computer scientists move away from &lt;span class="caps"&gt;GOTO&lt;/span&gt; statements in favor of the structured programming programming paradigm. Some programming style coding standards prohibit use of &lt;span class="caps"&gt;GOTO&lt;/span&gt; statements. &amp;#8211; &lt;a href="http://en.wikipedia.org/wiki/Goto#Criticism_of_goto_usage"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ruby takes the whole &lt;span class="caps"&gt;GOTO&lt;/span&gt; nonsense to an entirely new heights. Ruby&amp;#8217;s version of &lt;span class="caps"&gt;GOTO&lt;/span&gt;/&lt;span class="caps"&gt;LABEL&lt;/span&gt; is called &lt;a href="http://www.ruby-doc.org/core/classes/Kernel.html#M005933"&gt;throw/catch&lt;/a&gt;. The lunacy goes further as Ruby&amp;#8217;s &lt;em&gt;throw&lt;/em&gt; is equivalent to &lt;strong&gt;&lt;span class="caps"&gt;GOTO&lt;/span&gt; with a return value&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;hello&lt;/span&gt;
  throw &lt;span class="sy"&gt;:done&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;wtf&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;

catch(&lt;span class="sy"&gt;:done&lt;/span&gt;) { hello }
=&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;wtf&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Not only it makes the flow control hard to follow, it also shows your lack of fundamental programming skills. I&amp;#8217;d love to see a case where you use throw/catch because there&amp;#8217;s no other way. Only place I&amp;#8217;ve &lt;strong&gt;ever&lt;/strong&gt; used throw/catch is in my evil middleware &lt;a href="http://m.onkey.org/2009/1/15/the-evil-calls-back"&gt;Rack::Evil&lt;/a&gt;. And the name says it all.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s take a real example from Rails :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;find_with_associations&lt;/span&gt;(options = {})
  catch &lt;span class="sy"&gt;:invalid_query&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;
    join_dependency = &lt;span class="co"&gt;JoinDependency&lt;/span&gt;.new(&lt;span class="pc"&gt;self&lt;/span&gt;, merge_includes(scope(&lt;span class="sy"&gt;:find&lt;/span&gt;, &lt;span class="sy"&gt;:include&lt;/span&gt;), options[&lt;span class="sy"&gt;:include&lt;/span&gt;]), options[&lt;span class="sy"&gt;:joins&lt;/span&gt;])
    rows = select_all_rows(options, join_dependency)
    &lt;span class="r"&gt;return&lt;/span&gt; join_dependency.instantiate(rows)
  &lt;span class="r"&gt;end&lt;/span&gt;
  []
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Just by looking at this method, you&amp;#8217;ll have absolutely no idea who&amp;#8217;s gonna be throwing :invalid_query. It could be any method subsequently called while the block is being executed. Only way to know is by doing a global search for &lt;i&gt;throw :invalid_query&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Rails uses throw/catch here because it wants to return an empty array when something somewhere goes wrong. And the thing that can possibly go wrong is so deep down inside, throw/catch provides an easy way out without much refactoring. However, easy is not always the best way or the proper way.&lt;/p&gt;
&lt;p&gt;If we look at the relevant code from the involved methods :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;select_all_rows&lt;/span&gt;(options, join_dependency)
  connection.select_all(
    construct_finder_sql_with_included_associations(options, join_dependency),
    &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;name&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; Load Including Associations&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  )
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;construct_finder_sql_with_included_associations&lt;/span&gt;(options, join_dependency)
  scope = scope(&lt;span class="sy"&gt;:find&lt;/span&gt;)
  sql = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;SELECT &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;column_aliases(join_dependency)&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; FROM &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;(scope &amp;amp;&amp;amp; scope[&lt;span class="sy"&gt;:from&lt;/span&gt;]) || options[&lt;span class="sy"&gt;:from&lt;/span&gt;] || quoted_table_name&lt;span class="idl"&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;

  ....
  if !using_limitable_reflections?(join_dependency.reflections) &amp;amp;&amp;amp; ((scope &amp;amp;&amp;amp; scope[&lt;span class="sy"&gt;:limit&lt;/span&gt;]) || options[&lt;span class="sy"&gt;:limit&lt;/span&gt;])
    add_limited_ids_condition!(sql, options, join_dependency)
  &lt;span class="r"&gt;end&lt;/span&gt;
  ....

  sanitize_sql(sql)
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;add_limited_ids_condition!&lt;/span&gt;(sql, options, join_dependency)
  &lt;span class="r"&gt;unless&lt;/span&gt; (id_list = select_limited_ids_list(options, join_dependency)).empty?
    sql &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="idl"&gt;#{&lt;/span&gt;condition_word(sql)&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;connection.quote_table_name table_name&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;.&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;primary_key&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; IN (&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;id_list&lt;span class="idl"&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;span class="r"&gt;else&lt;/span&gt;
    throw &lt;span class="sy"&gt;:invalid_query&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This doesn&amp;#8217;t seem that bad on the first look. But think again. Apart from the control flow retardness, the method &lt;i&gt;add_limited_ids_condition&lt;/i&gt; adds an extra responsibility to the caller &amp;#8211; catching &lt;i&gt;invalid_query&lt;/i&gt;. And this is very easy to miss too &amp;#8211; as seen with the very same method in question here &amp;#8211; &lt;a href="http://github.com/rails/rails/blob/bf00de03dee5fba0b53f0fc1bb19464422550aa9/activerecord/lib/active_record/calculations.rb#L209"&gt;calculations.rb&lt;/a&gt;. Add a few of more throw/catch and you get a proper spaghetti code.&lt;/p&gt;
&lt;p&gt;I think the better way to write the above code is :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;find_with_associations&lt;/span&gt;(options = {})
  join_dependency = &lt;span class="co"&gt;JoinDependency&lt;/span&gt;.new(&lt;span class="pc"&gt;self&lt;/span&gt;, merge_includes(scope(&lt;span class="sy"&gt;:find&lt;/span&gt;, &lt;span class="sy"&gt;:include&lt;/span&gt;), options[&lt;span class="sy"&gt;:include&lt;/span&gt;]), options[&lt;span class="sy"&gt;:joins&lt;/span&gt;])
  rows = select_all_rows(options, join_dependency)
  rows ? join_dependency.instantiate(rows) : []
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;select_all_rows&lt;/span&gt;(options, join_dependency)
  finder_sql = construct_finder_sql_with_included_associations(options, join_dependency)
  connection.select_all(finder_sql, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;name&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; Load Including Associations&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; finder_sql
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;construct_finder_sql_with_included_associations&lt;/span&gt;(options, join_dependency)
  ....
  limitable = !using_limitable_reflections?(join_dependency.reflections) &amp;amp;&amp;amp; ((scope &amp;amp;&amp;amp; scope[&lt;span class="sy"&gt;:limit&lt;/span&gt;]) || options[&lt;span class="sy"&gt;:limit&lt;/span&gt;])

  &lt;span class="r"&gt;unless&lt;/span&gt; limitable &amp;amp;&amp;amp; add_limited_ids_condition!(sql, options, join_dependency).blank?
    ....
    sanitize_sql(sql)
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;add_limited_ids_condition!&lt;/span&gt;(sql, options, join_dependency)
  id_list = select_limited_ids_list(options, join_dependency)
  sql &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="idl"&gt;#{&lt;/span&gt;condition_word(sql)&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;connection.quote_table_name table_name&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;.&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;primary_key&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; IN (&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;id_list&lt;span class="idl"&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;span class="r"&gt;if&lt;/span&gt; id_list.present?
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I&amp;#8217;d normally say that you should be flexible about following such rules about using a pattern or not using some. But this is an exception. Using throw/catch is just fucking wrong. Plain and simple.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=-M-CGLeDnnE:GdpcsrEucIw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=-M-CGLeDnnE:GdpcsrEucIw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=-M-CGLeDnnE:GdpcsrEucIw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=-M-CGLeDnnE:GdpcsrEucIw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=-M-CGLeDnnE:GdpcsrEucIw: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=-M-CGLeDnnE:GdpcsrEucIw: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/-M-CGLeDnnE" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/ruby-i-don-t-like-2-catch-wtf-throw-wtf</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/58</id>
    <published>2009-08-03T17:16:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/oqDrsFW9Ai8/ruby-i-don-t-like-1-explicit-return" rel="alternate" />
    <title>Ruby I don't like #1 - Explicit 'return'</title>
    <content type="html">&lt;p&gt;In Ruby, you don&amp;#8217;t have to specify an explicit &lt;em&gt;return&lt;/em&gt; value from a method. Ruby will just return the last evaluated statement. Similarly, if an explicit &lt;em&gt;return&lt;/em&gt; statement will make itself the last evaluated statement &amp;#8211; i.e return control to the caller with the specified return value.&lt;/p&gt;
&lt;p&gt;However, I&amp;#8217;m not a big fan of explicit &lt;em&gt;return&lt;/em&gt; statements. In my experience, the only place where they make sense is in the first line of the method, where the control is returned to the caller if the supplied arguments are not valid/expected. Consider the following method :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;read&lt;/span&gt;(file_name, options = &lt;span class="pc"&gt;nil&lt;/span&gt;)
  &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="pc"&gt;nil&lt;/span&gt; &lt;span class="r"&gt;unless&lt;/span&gt; &lt;span class="co"&gt;File&lt;/span&gt;.exist?(file_name)
  ....
end&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I think the above is the only case where I feel it&amp;#8217;s ok to use an explicit &lt;em&gt;return&lt;/em&gt; as it&amp;#8217;s much better than the alternative &amp;#8211; wrapping the entire method in a big if block. Also, you don&amp;#8217;t really need to specify &lt;em&gt;nil&lt;/em&gt;. The above can be rewritten as :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;read&lt;/span&gt;(file_name, options = &lt;span class="pc"&gt;nil&lt;/span&gt;)
  &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="r"&gt;unless&lt;/span&gt; &lt;span class="co"&gt;File&lt;/span&gt;.exist?(file_name)
  ....
end&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now the real problem is visible when you look at the full method :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;read&lt;/span&gt;(file_name, options = &lt;span class="pc"&gt;nil&lt;/span&gt;)
  &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="pc"&gt;nil&lt;/span&gt; &lt;span class="r"&gt;unless&lt;/span&gt; &lt;span class="co"&gt;File&lt;/span&gt;.exist?(file_name)

  &lt;span class="r"&gt;if&lt;/span&gt; expires_in(options) &amp;gt; &lt;span class="i"&gt;0&lt;/span&gt;
    &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="pc"&gt;nil&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;

  &lt;span class="co"&gt;File&lt;/span&gt;.open(file_name, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) { |f| &lt;span class="co"&gt;Marshal&lt;/span&gt;.load(f) }
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A much simpler version of the above method is :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;read&lt;/span&gt;(file_name, options = &lt;span class="pc"&gt;nil&lt;/span&gt;)
  &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="co"&gt;File&lt;/span&gt;.exist?(file_name) &amp;amp;&amp;amp; expires_in(options) &amp;lt;= &lt;span class="i"&gt;0&lt;/span&gt;
    &lt;span class="co"&gt;File&lt;/span&gt;.open(file_name, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) { |f| &lt;span class="co"&gt;Marshal&lt;/span&gt;.load(f) }
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Of course there&amp;#8217;s no one ring to rule them all. It might be desirable to use multiple returns in a method. But every time you do that, take a moment to make sure it&amp;#8217;s making the code easier to read.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=oqDrsFW9Ai8:XIyQ2B5ASJU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=oqDrsFW9Ai8:XIyQ2B5ASJU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=oqDrsFW9Ai8:XIyQ2B5ASJU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=oqDrsFW9Ai8:XIyQ2B5ASJU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=oqDrsFW9Ai8:XIyQ2B5ASJU: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=oqDrsFW9Ai8:XIyQ2B5ASJU: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/oqDrsFW9Ai8" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/ruby-i-don-t-like-1-explicit-return</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/55</id>
    <published>2009-07-31T18:17:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/CXyzM5HyiyE/stop-returning-false-from-your-before-filters" rel="alternate" />
    <title>Stop returning false from your before filters</title>
    <content type="html">&lt;p&gt;In the past version of Rails you had to explicitly return &lt;tt&gt;false&lt;/tt&gt; from before filters to halt the filter chain and make sure the action doesn&amp;#8217;t get run. The code looked somewhat like :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;AdminController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;
  before_filter &lt;span class="sy"&gt;:check_admin&lt;/span&gt;

  private

  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;check_admin&lt;/span&gt;
    &lt;span class="r"&gt;unless&lt;/span&gt; current_user.admin?
      redirect_to home_path
      &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="pc"&gt;false&lt;/span&gt;
    &lt;span class="r"&gt;end&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But since &lt;strong&gt;&lt;a href="http://github.com/rails/rails/commit/f777ff72f931983946cbccbf2c64270922e93d84"&gt;Rails 2.0&lt;/a&gt;&lt;/strong&gt;, If you call &lt;strong&gt;&lt;em&gt;render&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;head&lt;/em&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;i&gt;redirect_to&lt;/i&gt;&lt;/strong&gt; from a &lt;i&gt;before_filter&lt;/i&gt;, the filter chain will be halted. So the above controller will now look like :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;AdminController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;
  before_filter &lt;span class="sy"&gt;:check_admin&lt;/span&gt;

  private

  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;check_admin&lt;/span&gt;
    redirect_to home_path &lt;span class="r"&gt;unless&lt;/span&gt; current_user.admin?
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should go ahead and update all your before filters to reflect this change. &lt;i&gt;return false&lt;/i&gt; is nothing but code smell.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=CXyzM5HyiyE:VUGAkrJbRek:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=CXyzM5HyiyE:VUGAkrJbRek:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=CXyzM5HyiyE:VUGAkrJbRek:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=CXyzM5HyiyE:VUGAkrJbRek:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=CXyzM5HyiyE:VUGAkrJbRek: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=CXyzM5HyiyE:VUGAkrJbRek: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/CXyzM5HyiyE" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/stop-returning-false-from-your-before-filters</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/57</id>
    <published>2009-07-29T19:37:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/2DRV6CUWJZg/running-rails-performance-tests-on-real-data" rel="alternate" />
    <title>Running Rails performance tests on real data</title>
    <content type="html">&lt;p&gt;It&amp;#8217;s not quite straight forward to run &lt;a href="http://guides.rubyonrails.org/performance_testing.html"&gt;Rails performance tests&lt;/a&gt; on real production data. By default, performance tests will use the &lt;em&gt;test&lt;/em&gt; database and wipe it before using it, thus making it impossible to put real data in the test database.&lt;/p&gt;
&lt;p&gt;To run performance tests on real data:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Create a file called &lt;i&gt;performance_test_helper.rb&lt;/i&gt; inside your &lt;em&gt;test/&lt;/em&gt; directory with the following:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# START : HAX HAX HAX&lt;/span&gt;
&lt;span class="c"&gt;# Load Rails environment in 'test' mode&lt;/span&gt;
&lt;span class="co"&gt;RAILS_ENV&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
require &lt;span class="co"&gt;File&lt;/span&gt;.expand_path(&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;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/../config/environment&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
&lt;span class="c"&gt;# Re-establish db connection for 'performance' mode&lt;/span&gt;
silence_warnings { &lt;span class="co"&gt;RAILS_ENV&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;performance&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; }
&lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;.establish_connection
&lt;span class="c"&gt;# STOP : HAX HAX HAX&lt;/span&gt;

require_dependency &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;application&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&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;
require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;active_support/test_case&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;action_controller/test_case&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;action_controller/integration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;

require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;performance_test_help&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
	&lt;li&gt;Replace the following lines in performance tests:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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_helper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;
require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;performance_test_help&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;with&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;performance_test_helper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
	&lt;li&gt;Supply configuration for &lt;em&gt;&amp;#8216;performance&amp;#8217;&lt;/em&gt; environment in your &lt;em&gt;database.yml&lt;/em&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;performance:
  &lt;span class="sy"&gt;adapter:&lt;/span&gt; mysql
  &lt;span class="sy"&gt;encoding:&lt;/span&gt; utf8
  &lt;span class="sy"&gt;database:&lt;/span&gt; database_with_real_data
  &lt;span class="sy"&gt;pool:&lt;/span&gt; &lt;span class="i"&gt;5&lt;/span&gt;
  &lt;span class="sy"&gt;username:&lt;/span&gt; root
  password:
  &lt;span class="sy"&gt;socket:&lt;/span&gt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;tmp&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="mod"&gt;m&lt;/span&gt;&lt;/span&gt;ysql.sock&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above steps will also make sure that the performance tests use the database &lt;i&gt;database_with_real_data&lt;/i&gt;. Also, the database will not get wiped on every run. You&amp;#8217;ll also have to ensure the test database &amp;#8211; &lt;i&gt;database_with_real_data&lt;/i&gt; &amp;#8211; is up-to-date with the schema changes.&lt;/p&gt;
&lt;p&gt;Now you can just run your performance tests using the usual rake tasks:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="er"&gt;$&lt;/span&gt; rake test&lt;span class="sy"&gt;:benchmark&lt;/span&gt;
&lt;span class="er"&gt;$&lt;/span&gt; rake test&lt;span class="sy"&gt;:profile&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=2DRV6CUWJZg:YcqP2PfE_JI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=2DRV6CUWJZg:YcqP2PfE_JI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=2DRV6CUWJZg:YcqP2PfE_JI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=2DRV6CUWJZg:YcqP2PfE_JI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=2DRV6CUWJZg:YcqP2PfE_JI: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=2DRV6CUWJZg:YcqP2PfE_JI: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/2DRV6CUWJZg" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/running-rails-performance-tests-on-real-data</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/56</id>
    <published>2009-07-07T22:21:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/Ov3q-LhNMrA/nested-layouts" rel="alternate" />
    <title>Nested Layouts</title>
    <content type="html">&lt;p&gt;Don&amp;#8217;t think the nested layouts get any simpler in Rails.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;parent_layout&lt;/span&gt;(layout)
    &lt;span class="iv"&gt;@content_for_layout&lt;/span&gt; = &lt;span class="pc"&gt;self&lt;/span&gt;.output_buffer
    &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="idl"&gt;#{&lt;/span&gt;layout&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# items.html.erb&lt;/span&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;
&amp;lt;%= yield %&amp;gt;

&amp;lt;% parent_layout 'master' %&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and the parent layout of &lt;em&gt;items&lt;/em&gt; &amp;#8211; the &lt;em&gt;master&lt;/em&gt; layout :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# master.html.erb&lt;/span&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;
  &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;
  &amp;lt;body&amp;gt;
    &amp;lt;&lt;span class="s"&gt;&lt;span class="dl"&gt;%=&lt;/span&gt;&lt;span class="k"&gt; yield %&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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=Ov3q-LhNMrA:NY-giOmSqTw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=Ov3q-LhNMrA:NY-giOmSqTw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=Ov3q-LhNMrA:NY-giOmSqTw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=Ov3q-LhNMrA:NY-giOmSqTw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=Ov3q-LhNMrA:NY-giOmSqTw: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=Ov3q-LhNMrA:NY-giOmSqTw: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/Ov3q-LhNMrA" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/nested-layouts</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/53</id>
    <published>2009-03-24T10:28:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/CkXvUxhZbAc/default-scopes-and-inheritance-to-the-rescue" rel="alternate" />
    <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_. 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&lt;/em&gt;scope&lt;/i&gt; called &lt;em&gt;approved&lt;/em&gt;:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;
  has_many &lt;span class="sy"&gt;:tags&lt;/span&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;
  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;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And now I&amp;#8217;d have to use &lt;em&gt;Item.approved.&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&amp;#8217; inheritance:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;
  has_many &lt;span class="sy"&gt;:tags&lt;/span&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;span class="r"&gt;end&lt;/span&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;
  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;
  set_inheritance_column &lt;span class="pc"&gt;nil&lt;/span&gt; &lt;span class="c"&gt;# hax?&lt;/span&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;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Checking this on console :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;gt;&amp;gt; p = PublishedItem.first
  SELECT * FROM `items` WHERE (`items`.`published` = 1) ORDER BY items.name ASC LIMIT 1

&amp;gt;&amp;gt; i = Item.first
  SELECT * FROM `items` ORDER BY items.name ASC LIMIT 1&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;
  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;
  has_many &lt;span class="sy"&gt;:tags&lt;/span&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;span class="r"&gt;end&lt;/span&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;
  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;
  set_inheritance_column &lt;span class="pc"&gt;nil&lt;/span&gt; &lt;span class="c"&gt;# hax?&lt;/span&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;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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;STI_. It&amp;#8217;s using &lt;i&gt;set_inheritance&lt;/em&gt;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=CkXvUxhZbAc:eahufXkj5Gk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=CkXvUxhZbAc:eahufXkj5Gk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=CkXvUxhZbAc:eahufXkj5Gk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=CkXvUxhZbAc:eahufXkj5Gk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=CkXvUxhZbAc:eahufXkj5Gk: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=CkXvUxhZbAc:eahufXkj5Gk: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/CkXvUxhZbAc" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/default-scopes-and-inheritance-to-the-rescue</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/52</id>
    <published>2009-03-18T12:42:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/3kRqx337SOQ/my-rails-guides" rel="alternate" />
    <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; &amp;#8211; Overview of Rails&amp;#8217; 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; &amp;#8211; Using Rails&amp;#8217; 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&amp;#8217;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=3kRqx337SOQ:nxOyEKlXOtE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=3kRqx337SOQ:nxOyEKlXOtE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=3kRqx337SOQ:nxOyEKlXOtE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=3kRqx337SOQ:nxOyEKlXOtE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=3kRqx337SOQ:nxOyEKlXOtE: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=3kRqx337SOQ:nxOyEKlXOtE: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/3kRqx337SOQ" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/my-rails-guides</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/51</id>
    <published>2009-03-17T15:49:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/VmEs2WMiIOQ/assert_-and-assert_not_" rel="alternate" />
    <title>assert_* and assert_not_*</title>
    <content type="html">&lt;p&gt;Not sure I like this or not, but I&amp;#8217;m gonna give it a shot in the &amp;#8220;real world&amp;#8221; nevertheless.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;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;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;

    method = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;&lt;span class="gv"&gt;$2&lt;/span&gt;&lt;span class="idl"&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;
    object = arguments.first

    &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="gv"&gt;$1&lt;/span&gt;
      arguments.each &lt;span class="r"&gt;do&lt;/span&gt; |object|
        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="idl"&gt;#{&lt;/span&gt;method&lt;span class="idl"&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="idl"&gt;#{&lt;/span&gt;object&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="r"&gt;end&lt;/span&gt;
    &lt;span class="r"&gt;else&lt;/span&gt;
      arguments.each &lt;span class="r"&gt;do&lt;/span&gt; |object|
        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="idl"&gt;#{&lt;/span&gt;method&lt;span class="idl"&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="idl"&gt;#{&lt;/span&gt;object&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="r"&gt;end&lt;/span&gt;
    &lt;span class="r"&gt;end&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ActiveSupport::TestCase&lt;/span&gt;
  include &lt;span class="co"&gt;AssertionExtensions&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now using this in your tests:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;test_is_admin&lt;/span&gt;
  &lt;span class="c"&gt;# [people(:admin), people(:superuser)].each {|p| assert p.admin?}&lt;/span&gt;
  assert_admin people(&lt;span class="sy"&gt;:admin&lt;/span&gt;), people(&lt;span class="sy"&gt;:superuser&lt;/span&gt;)

  &lt;span class="c"&gt;# assert ! people(:foo).admin?&lt;/span&gt;
  assert_not_admin people(&lt;span class="sy"&gt;:foo&lt;/span&gt;)
&lt;span class="r"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=VmEs2WMiIOQ:x-j64L48UoE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=VmEs2WMiIOQ:x-j64L48UoE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=VmEs2WMiIOQ:x-j64L48UoE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=VmEs2WMiIOQ:x-j64L48UoE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=VmEs2WMiIOQ:x-j64L48UoE: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=VmEs2WMiIOQ:x-j64L48UoE: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/VmEs2WMiIOQ" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/assert_-and-assert_not_</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/50</id>
    <published>2009-03-14T12:51:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/tdfZQNAbu_A/make-test-unit-display-errors-earlier" rel="alternate" />
    <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;div class="CodeRay"&gt;
  &lt;div 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;
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;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Test::Unit::UI::Console::TestRunner&lt;/span&gt;
  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;add_fault&lt;/span&gt;(fault)
    hax_output(fault)
    &lt;span class="iv"&gt;@faults&lt;/span&gt; &amp;lt;&amp;lt; fault
    output_single(fault.single_character_display, &lt;span class="i"&gt;1&lt;/span&gt;)
    &lt;span class="iv"&gt;@already_outputted&lt;/span&gt; = &lt;span class="pc"&gt;true&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;

  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;hax_output&lt;/span&gt;(fault)
    &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;)
    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;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;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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=tdfZQNAbu_A:z--IaFeUOto:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=tdfZQNAbu_A:z--IaFeUOto:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=tdfZQNAbu_A:z--IaFeUOto:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=tdfZQNAbu_A:z--IaFeUOto:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=tdfZQNAbu_A:z--IaFeUOto: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=tdfZQNAbu_A:z--IaFeUOto: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/tdfZQNAbu_A" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/make-test-unit-display-errors-earlier</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/49</id>
    <published>2009-01-15T17:54:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/rOKFrhw5Szc/the-evil-calls-back" rel="alternate" />
    <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&amp;#8217;t already know what is &lt;a href="http://github.com/rtomayko/rack-contrib"&gt;rack-contrib&lt;/a&gt;, it&amp;#8217;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 style="text-align:center;"&gt;Rack::Evil&lt;/h2&gt;
&lt;p&gt;The name says it all. It&amp;#8217;s pure evil, as it enables the rack application to return the response from any place during while it&amp;#8217;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;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;app = lambda &lt;span class="r"&gt;do&lt;/span&gt; |env|
  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;
  Hello Template
  &amp;lt;%= throw :response, [404, {'Content-Type' =&amp;gt; 'text/html'}, 'From Template'] %&amp;gt;
  Never&lt;/span&gt;&lt;span class="dl"&gt;
  TEMPLATE&lt;/span&gt;&lt;/span&gt;
  result = &lt;span class="co"&gt;ERB&lt;/span&gt;.new(template).result(binding)

  [&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;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And the response reaching the client will not be &amp;#8220;&lt;em&gt;Ran the template&lt;/em&gt;&amp;#8221; with &lt;em&gt;200&lt;/em&gt; status. But it&amp;#8217;ll be &amp;#8220;&lt;em&gt;From Template&lt;/em&gt;&amp;#8221; with &lt;em&gt;404&lt;/em&gt; status!&lt;/p&gt;
&lt;h2 style="text-align:center;"&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&amp;#8217;t think that&amp;#8217;s the best way moving forward. That&amp;#8217;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;div class="CodeRay"&gt;
  &lt;div 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;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;initialize&lt;/span&gt;(default)
    &lt;span class="iv"&gt;@default&lt;/span&gt; = default
  &lt;span class="r"&gt;end&lt;/span&gt;

  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;call&lt;/span&gt;(env)
    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;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;

&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CompressBody&lt;/span&gt;
  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;call&lt;/span&gt;(response)
    status, headers, body = response

    compressed_body = zip_body(body)
    [status, headers, compressed_body]
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&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;
  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;

  run &lt;span class="co"&gt;YourPrimaryRackApp&lt;/span&gt;.new

  after &lt;span class="co"&gt;CompressBody&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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&amp;#8230;.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&amp;#8230;.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/~ff/monkeyonrails?a=rOKFrhw5Szc:x_4Mo2d_tAA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=rOKFrhw5Szc:x_4Mo2d_tAA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=rOKFrhw5Szc:x_4Mo2d_tAA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=rOKFrhw5Szc:x_4Mo2d_tAA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=rOKFrhw5Szc:x_4Mo2d_tAA: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=rOKFrhw5Szc:x_4Mo2d_tAA: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/rOKFrhw5Szc" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/the-evil-calls-back</feedburner:origLink></entry>
  <entry>
    <id>tag:m.onkey.org,2005:Entry/48</id>
    <published>2008-12-04T00:50:00Z</published>
    <updated>2010-11-17T13:38:07Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/monkeyonrails/~3/0j127cY9Ss0/rails-templates" rel="alternate" />
    <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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&gt;
&lt;p&gt;A very simple template would look like :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# template.rb&lt;/span&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;
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;)
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;
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;)

git &lt;span class="sy"&gt;:init&lt;/span&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;
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;/div&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;#8217;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&amp;#8217;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;div class="CodeRay"&gt;
  &lt;div 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;
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;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&gt;
&lt;p&gt;And let Rails take care of installing the required gems if they&amp;#8217;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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can even install plugins as git submodules :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&gt;
&lt;h4&gt;initializer(filename, data = nil, &amp;amp;block)&lt;/h4&gt;
&lt;p&gt;Adds an initializer to the generated application&amp;#8217;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;div class="CodeRay"&gt;
  &lt;div 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;
class Object
  def not_nil?
    !nil?
  end

  def not_blank?
    !blank?
  end
end&lt;/span&gt;&lt;span class="dl"&gt;
CODE&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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;RAILS_ROOT&lt;/em&gt; and creates all the directories/file needed :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;
class Foo
end&lt;/span&gt;&lt;span class="dl"&gt;
CODE&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;#8217;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;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;div class="CodeRay"&gt;
  &lt;div 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;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;
    namespace :boot do
      task :strap do
        puts &amp;quot;i like boots!&amp;quot;
      end
    end&lt;/span&gt;&lt;span class="dl"&gt;
  TASK&lt;/span&gt;&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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&amp;#8217;m playing with Rails :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&gt;
&lt;h4&gt;rake(command, options = {})&lt;/h4&gt;
&lt;p&gt;So you scaffolded, but who&amp;#8217;s gonna run the &lt;em&gt;db:migrate&lt;/em&gt; rake task !? Here&amp;#8217;s who :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&gt;
&lt;p&gt;Or even use sudo :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&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;div class="CodeRay"&gt;
  &lt;div 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;
  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;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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&amp;#8217;re adding :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;)
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;)

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;
class Shiny
end&lt;/span&gt;&lt;span class="dl"&gt;
CODE&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&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&amp;#8217;s answer. Lets say you want to freeze rails only if the user want to :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&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; &amp;#8220;-a love&amp;#8221;)&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;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;git &lt;span class="sy"&gt;:init&lt;/span&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;
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;/div&gt;
&lt;/div&gt;
&lt;h2 style="text-align:center;"&gt;And bort ?&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s what a bort template would look like :&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# bort.rb&lt;/span&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;
  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;span class="r"&gt;end&lt;/span&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;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;
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;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;
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;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;
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;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;
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;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;
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;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;
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;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;

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;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;
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;
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;

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;)

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;)
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;/div&gt;
&lt;/div&gt;
&lt;p&gt;Shamelessly inspired/yanked from &lt;a href="http://github.com/jeremymcanally/rails-templates/tree/master/bort.template"&gt;Jeremy&amp;#8217;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;div class="CodeRay"&gt;
  &lt;div 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;/div&gt;
&lt;/div&gt;
&lt;h2 style="text-align:center;"&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&amp;#8217;s&lt;/a&gt; &lt;a href="http://github.com/jeremymcanally/rails-templates/tree/master"&gt;rails-templates project&lt;/a&gt; &amp;#8211; 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&lt;/span&gt; 1&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;br /&gt;
&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt; 2&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/~ff/monkeyonrails?a=0j127cY9Ss0:B4K-G7iXmTI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=0j127cY9Ss0:B4K-G7iXmTI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=0j127cY9Ss0:B4K-G7iXmTI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/monkeyonrails?i=0j127cY9Ss0:B4K-G7iXmTI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/monkeyonrails?a=0j127cY9Ss0:B4K-G7iXmTI: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=0j127cY9Ss0:B4K-G7iXmTI: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/0j127cY9Ss0" height="1" width="1"/&gt;</content>
    <author>
      <name>Pratik Naik</name>
    </author>
  <feedburner:origLink>http://m.onkey.org/rails-templates</feedburner:origLink></entry>
</feed>
