<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Planetaki Planet Ruby on Rails</title>
  <link rel="alternate" href="http://www.planetaki.com/ror"/>
  <updated>2008-05-28T09:16:25+00:00</updated>
  <id>planetaki.com:905</id>
  <author>
    <name>Planetaki - Planet Ruby on Rails</name>
    <email>hello@planetaki.com</email>
  </author>
  <entry>
    <title>Named Scope: It's Not Just for Conditions, Ya Know?</title>
    <updated>2008-08-20T15:52:02+00:00</updated>
    <published>2008-08-20T14:47:00+00:00</published>
    <id>planetaki.com:905:post:6368500</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/RyansScraps/~3/370044913/named-scope-it-s-not-just-for-conditions-ya-know"/>
    <summary type="html">&lt;p&gt;&lt;a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality" target="_blank"&gt;Named scopes in Rails are great&lt;/a&gt;, everybody knows that.  They&#8217;re usually used to create granular, chainable sets of &lt;span class="caps"&gt;SQL&lt;/span&gt; conditions that nicely encapsulate your domain query logic.  Here&#8217;s a simple example:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Article&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Get all articles that have been published&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  named_scope &lt;span class="sy"&gt;:published&lt;/span&gt;, &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;published = ?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="pc"&gt;true&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Get all articles that were created recently&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  named_scope &lt;span class="sy"&gt;:recent&lt;/span&gt;, lambda { { &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;= ?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="i"&gt;1&lt;/span&gt;.week.ago] } }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get all recently created articles that have been published&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.published.recent &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;However, as much as I use &lt;code&gt;named_scope&lt;/code&gt; for this purpose, I also use it for some smaller and still useful functions.  For instance, I find that I often need to just fetch the first X number of results for any particular query.  Instead of having to call &lt;code&gt;find&lt;/code&gt; with the &lt;code&gt;:limit&lt;/code&gt; option you could create the following named_scope:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Article&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Only get the first X results&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  named_scope &lt;span class="sy"&gt;:limited&lt;/span&gt;, lambda { |num| { &lt;span class="sy"&gt;:limit&lt;/span&gt; =&amp;gt; num } }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get the first 5 articles - instead of Article.find(:all, :limit =&amp;gt; 5)&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.limited(&lt;span class="i"&gt;5&lt;/span&gt;) &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Hey, any less typing I&#8217;ll take, and I find myself using this &lt;code&gt;limited&lt;/code&gt; named_scope a lot.  But let&#8217;s pimp it a little so that you don&#8217;t always have to supply the number, and make it default to the &lt;code&gt;per_page&lt;/code&gt; value that exists on the class if you&#8217;re using &lt;a href="http://github.com/mislav/will_paginate/tree/master" target="_blank"&gt;will_paginate&lt;/a&gt;.&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Article&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Only get the first X results.  If no arg is given then try to&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# use the per_page value that will_paginate uses.  If that&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# doesn't exist then use 10&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  named_scope &lt;span class="sy"&gt;:limited&lt;/span&gt;, lambda { |*num|&lt;tt&gt;
&lt;/tt&gt;    { &lt;span class="sy"&gt;:limit&lt;/span&gt; =&amp;gt; num.flatten.first || (&lt;span class="r"&gt;defined?&lt;/span&gt;(per_page) ? per_page : &lt;span class="i"&gt;10&lt;/span&gt;) }&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;per_page&lt;/span&gt;; &lt;span class="i"&gt;15&lt;/span&gt;; &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get the first 15 articles&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.limited &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get the first 5 articles&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.limited(&lt;span class="i"&gt;5&lt;/span&gt;) &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Note that we have to use the variable length &lt;code&gt;*num&lt;/code&gt; argument in the &lt;code&gt;lambda&lt;/code&gt; to allow for no arguments.&lt;/p&gt;


	&lt;p&gt;Cool, so we&#8217;ve got a handy little tool for our toolbox now.  Here&#8217;s another one I find myself using that isn&#8217;t strictly a conditional scope &#8211; &lt;code&gt;ordered&lt;/code&gt;:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Article&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Order the results by the given argument, or 'created_at DESC'&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# if no arg is given&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  named_scope &lt;span class="sy"&gt;:ordered&lt;/span&gt;, lambda { |*order|&lt;tt&gt;
&lt;/tt&gt;    { &lt;span class="sy"&gt;:order&lt;/span&gt; =&amp;gt; order.flatten.first || &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;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get all articles ordered by 'created_at DESC'&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.ordered &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get all articles ordered by 'updated_at DESC'&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.ordered(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;updated_at DESC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;I&#8217;ve bundled these scopes up into a &#8220;utility scopes:http://github.com/yfactorial/utility_scopes&#8221; plugin/gem if you think they look useful to you.  I&#8217;ve also added some class-level convenience initializers to let you override the default values (like the default limit and default order clause):&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Article&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# This class's default ordering (if not specified&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# defaults to 'created_at DESC'&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  ordered_by &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;published_at DESC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# By default, return 15 results (if not specified&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# defaults to 10&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  default_limit &lt;span class="i"&gt;15&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get the first 15 articles ordered by 'published_at DESC'&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.ordered.limited &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get the first 15 articles ordered by 'popularity ASC'&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.ordered(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;popularity ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).limited &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get the first 20 articles ordered by 'popularity ASC'&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.ordered(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;popularity ASC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).limited(&lt;span class="i"&gt;20&lt;/span&gt;) &lt;span class="c"&gt;#=&amp;gt; [&amp;lt;Article id: ...&amp;gt;, &amp;lt;..&amp;gt;]&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Need a little something else?  How about the &lt;code&gt;with&lt;/code&gt; scope which will eager load the specified associations:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Article&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has_many &lt;span class="sy"&gt;:comments&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has_many &lt;span class="sy"&gt;:contributors&lt;/span&gt;, &lt;span class="sy"&gt;:class_name&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Get the first 10 articles along with their comments, comment authors and article contributors&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.limit(&lt;span class="i"&gt;10&lt;/span&gt;).with({ &lt;span class="sy"&gt;:comments&lt;/span&gt; =&amp;gt; &lt;span class="sy"&gt;:author&lt;/span&gt; }, &lt;span class="sy"&gt;:contributors&lt;/span&gt;)&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;You can get all these goodies yourself by doing the following in your Rails 2.1 app.  In &lt;code&gt;config/environment.rb&lt;/code&gt; specify the gem dependency:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;Rails&lt;/span&gt;::&lt;span class="co"&gt;Initializer&lt;/span&gt;.run &lt;span class="r"&gt;do&lt;/span&gt; |config|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  config.gem &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;yfactorial-utility_scopes&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&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;utility_scopes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="sy"&gt;:source&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;http://gems.github.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And then to get the &lt;code&gt;utility_scopes&lt;/code&gt; gem actually installed on your system:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;rake gems:install GEM=yfactorial-utility_scopes&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Or you can just install the gem as you normally would:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;sudo gem install yfactorial-utility_scopes -s http://gems.github.com&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Independent of whether or not you find these scopes useful, remember that &lt;code&gt;named_scope&lt;/code&gt; is all up in your queries&#8217; bidness &#8211; not just your queries&#8217; conditions&lt;/p&gt;


	&lt;p&gt;Have some utility scopes you find to be indispensable?  Let me know here or send me a request on github (user is &lt;a href="http://github.com/yfactorial" target="_blank"&gt;yfactorial&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;tags: &lt;a href="http://technorati.com/tag/ruby" target="_blank"&gt;ruby&lt;/a&gt;,
&lt;a href="http://technorati.com/tag/rubyonrails" target="_blank"&gt;rubyonrails&lt;/a&gt;&lt;/p&gt;
          
&lt;p&gt;&lt;map name="google_ad_map_IqsNMDj8f7PkHFgEt2fS36JqHvI_"&gt;&lt;area href="http://imageads.googleadservices.com/pagead/imgclick/IqsNMDj8f7PkHFgEt2fS36JqHvI_?pos=0" shape="rect" coords="1,2,367,28" /&gt;&lt;area href="http://services.google.com/feedback/abg" shape="rect" coords="384,10,453,23" /&gt;&lt;/map&gt;&lt;img src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-5311481257402216&amp;channel=7127926294&amp;output=png&amp;cuid=IqsNMDj8f7PkHFgEt2fS36JqHvI_&amp;url=http%3A%2F%2Fryandaigle.com%2Farticles%2F2008%2F8%2F20%2Fnamed-scope-it-s-not-just-for-conditions-ya-know" border="0" onload="resizeImage( this )" usemap="http://ryandaigle.com/#google_ad_map_IqsNMDj8f7PkHFgEt2fS36JqHvI_" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RyansScraps?a=gaCtwb" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~a/RyansScraps?i=gaCtwb" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RyansScraps?a=Rc7baK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/RyansScraps?i=Rc7baK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RyansScraps?a=CimPpK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/RyansScraps?i=CimPpK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RyansScraps?a=QLR9XK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/RyansScraps?i=QLR9XK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RyansScraps?a=obOGRk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/RyansScraps?i=obOGRk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;</summary>
    <source>
      <id>tag:ryandaigle.com,2008-08-20:7467</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/RyansScraps/~3/370044913/named-scope-it-s-not-just-for-conditions-ya-know"/>
      <title>Named Scope: It's Not Just for Conditions, Ya Know?</title>
      <updated>2008-08-20T15:52:02+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Web Spidering con Ruby on Rails, el v&#237;deo de Volcanica</title>
    <updated>2008-08-20T12:53:50+00:00</updated>
    <published>2008-08-20T12:09:26+00:00</published>
    <id>planetaki.com:905:post:6358554</id>
    <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/20/web-spidering-con-ruby-on-rails-el-video-de-volcanica/"/>
    <summary type="html">&lt;p&gt;&lt;strong&gt;Boris, la ara&#241;a volc&#225;nica, la pel&#237;cula:&lt;/strong&gt; &lt;img class="wp-smiley" src="http://www.jaimeiniesta.com/wp-includes/images/smilies/icon_smile.gif" onload="resizeImage( this )" alt=":)" /&gt;&lt;br /&gt;
&lt;object height="420" width="500"&gt;&lt;param name="src" value="http://blip.tv/play/qjnI8WiKqH0" /&gt;&lt;embed src="http://blip.tv/play/qjnI8WiKqH0" type="application/x-shockwave-flash" height="420" width="500"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8230;este es el v&#237;deo de la charla sobre web spidering que dirig&#237; el a&#241;o pasado en &lt;a href="http://volcanica.cat" target="_blank"&gt;Volcanica&lt;/a&gt;. El sonido no es muy bueno porque hab&#237;a ruido de fondo de la sala de al lado pero se agradece de todos modos!&lt;/p&gt;
&lt;p&gt;Tambi&#233;n est&#225;n disponibles las presentaciones para su descarga: &lt;a href="http://www.volcanica.cat/wp-content/uploads/2008/08/introduccion_ruby_on_rails.pdf" target="_blank"&gt;introduccion_ruby_on_rails&lt;/a&gt; y &lt;a href="http://www.volcanica.cat/wp-content/uploads/2008/08/ruby-web_spidering.odp" target="_blank"&gt;ruby-web_spidering&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Puedes ver los &lt;a href="http://www.volcanica.cat/?p=42" target="_blank"&gt;v&#237;deos de todo Volcanica 2007 en su web&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Este a&#241;o cambiar&#233; de tema y hablar&#233; &lt;a href="http://www.jaimeiniesta.com/2008/08/12/charlas-sobre-ruby-y-shoes-en-volcanica/" target="_blank"&gt;s&#243;lo de Ruby&lt;/a&gt;. &lt;img class="wp-smiley" src="http://www.jaimeiniesta.com/wp-includes/images/smilies/icon_razz.gif" onload="resizeImage( this )" alt=":P" /&gt;&lt;/p&gt;</summary>
    <source>
      <id>http://www.jaimeiniesta.com/?p=192</id>
      <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/20/web-spidering-con-ruby-on-rails-el-video-de-volcanica/"/>
      <title>Web Spidering con Ruby on Rails, el v&#237;deo de Volcanica</title>
      <updated>2008-08-20T12:53:50+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>C&#243;mo evitar la regeneraci&#243;n de thumbnails con attachment_fu</title>
    <updated>2008-08-20T09:19:54+00:00</updated>
    <published>2008-08-20T09:15:10+00:00</published>
    <id>planetaki.com:905:post:6347857</id>
    <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/20/como-evitar-la-regeneracion-de-thumbnails-con-attachment_fu/"/>
    <summary type="html">&lt;p&gt;&lt;a href="http://svn.techno-weenie.net/projects/plugins/attachment_fu/" target="_blank"&gt;attachment_fu&lt;/a&gt; es seguramente el plugin de subida de adjuntos m&#225;s usado actualmente en el mundillo Rails, aunque seguido bastante de cerca por el nuevo y tambi&#233;n recomendable &lt;a href="http://www.thoughtbot.com/projects/paperclip" target="_blank"&gt;paperclip&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Un comportamiento que no me gusta de attachment_fu es que tras cada actualizaci&#243;n del modelo, regenera el conjunto de thumbnails. Est&#225; bien que tras la creaci&#243;n de la foto procese la imagen para generar todos sus thumbnails, pero no me parece buena idea que si simplemente quieres actualizar cualquier otro dato del modelo, se vuelva a regenerar el conjunto de thumbnails.&lt;/p&gt;
&lt;p&gt;Por ejemplo, si tienes un modelo Foto con todos los campos de attachment_fu pero adem&#225;s un campo t&#237;tulo&amp;#8230; cada vez que actualices la foto aunque s&#243;lo sea para cambiarle el t&#237;tulo, se volver&#225; a procesar la imagen para generar los thumbnails, d&#225;ndole carga innecesaria al servidor.&lt;/p&gt;
&lt;p&gt;Afortunadamente esto es c&#243;digo libre y f&#225;cil de entender as&#237; que mirando el fichero &lt;a href="http://svn.techno-weenie.net/projects/plugins/attachment_fu/lib/technoweenie/attachment_fu.rb" target="_blank"&gt;attachment_fu.rb&lt;/a&gt;, podemos encontrar esta l&#237;nea que es la que hace que tras cada .save del modelo se procese el adjunto:&lt;/p&gt;
&lt;div class="dean_ch"&gt;
&lt;ol&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;base.&lt;span class="kw5"&gt;after_save&lt;/span&gt; &lt;span class="re3"&gt;:after_process_attachment&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;basta con cambiarla a esto:&lt;/p&gt;
&lt;div class="dean_ch"&gt;
&lt;ol&gt;
&lt;li class="li1"&gt;
&lt;div class="de1"&gt;base.&lt;span class="kw5"&gt;after_create&lt;/span&gt; &lt;span class="re3"&gt;:after_process_attachment&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;para que s&#243;lo lo haga tras la creaci&#243;n del adjunto, y no en sucesivas actualizaciones.&lt;/p&gt;
&lt;p&gt;Ser&#237;a interesante mirarlo m&#225;s en profundidad para que s&#237; lo haga en caso de que le estemos pasando un nuevo fichero de imagen, pero por el momento me vale para mis prop&#243;sitos&amp;#8230; y de todos modos quiz&#225; es hora de irse cambiando a paperclip, que por lo que tengo entendido, no tiene este comportamiento&amp;#8230; aunque tampoco es del todo c&#243;modo porque he le&#237;do que &lt;a href="http://codetocustomer.com/blog/2008/07/regenerate-paperclip-thumbnails" target="_blank"&gt;para regenerar los thumbnails en paperclip es necesario lanzar una tarea rake&lt;/a&gt;.&lt;/p&gt;</summary>
    <source>
      <id>http://www.jaimeiniesta.com/?p=189</id>
      <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/20/como-evitar-la-regeneracion-de-thumbnails-con-attachment_fu/"/>
      <title>C&#243;mo evitar la regeneraci&#243;n de thumbnails con attachment_fu</title>
      <updated>2008-08-20T09:19:54+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Cerrado por vacaciones</title>
    <updated>2008-08-19T17:10:27+00:00</updated>
    <published>2008-08-19T15:41:30+00:00</published>
    <id>planetaki.com:905:post:6310833</id>
    <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/19/cerrado-por-vacaciones/"/>
    <summary type="html">&lt;p&gt;Tras largos meses de intensa actividad haciendo malabarismos entre varios proyectos, lleg&#243; al fin el momento de la pausa veraniega. &#161;Me marcho de vacaciones hasta el &lt;strong&gt;8 de septiembre&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;Aprovechar&#233; para descansar, montar en bici, dar largos paseos, descubrir alguna ciudad nueva si me lo permite Ryanair y, por qu&#233; no, estudiar alguno de esos libros de Ruby que compr&#233; en su d&#237;a y tan buena pinta tienen.&lt;/p&gt;
&lt;p&gt;Nos vemos a la vuelta! Que descans&#233;is tambi&#233;n vosotros! &lt;img class="wp-smiley" src="http://www.jaimeiniesta.com/wp-includes/images/smilies/icon_smile.gif" onload="resizeImage( this )" alt=":)" /&gt;&lt;/p&gt;</summary>
    <source>
      <id>http://www.jaimeiniesta.com/?p=186</id>
      <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/19/cerrado-por-vacaciones/"/>
      <title>Cerrado por vacaciones</title>
      <updated>2008-08-19T17:10:27+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>My attempt at sake task management</title>
    <updated>2008-08-19T04:55:32+00:00</updated>
    <published>2008-08-19T04:02:11+00:00</published>
    <id>planetaki.com:905:post:6277594</id>
    <link rel="alternate" href="http://drnicwilliams.com/2008/08/19/my-attempt-at-sake-task-management/"/>
    <summary type="html">&lt;p&gt;&lt;a href="http://www.kitchenzing.com/product.php?pcode=SBB888" target="_blank"&gt;&lt;img class="alignright" src="http://www.kitchenzing.com/images/products/SB888-6piecesake.jpg" border="0" onload="resizeImage( this )" alt="Sake set" width="200" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve used &lt;a href="http://errtheblog.com/posts/60-sake-bomb" target="_blank"&gt;sake&lt;/a&gt; intermittently in my workflow. It competes against me writing helper/admin scripts in my &lt;code&gt;~/ruby/bin&lt;/code&gt; folder. Normally, executable Ruby scripts have won. But I think I have a new solution that could make sake a permanent winner for me.&lt;/p&gt;
&lt;p&gt;Ruby scripts are easy to create and execute. You just open new file, change the TextMate grammar to &amp;#8216;Ruby&amp;#8217;, type &amp;#8216;rb&amp;#8217; and press TAB and you&amp;#8217;re off and running (the &amp;#8216;rb&amp;#8217; snippet generates &lt;code&gt;#!/usr/bin/env ruby&lt;/code&gt; or a variation of that). You then make the file executable and BAM! you can run the script from any folder in your environment.&lt;/p&gt;
&lt;p&gt;Sake tasks are more annoying to write. After creating a new file, you need to create the namespace and task wrappers for your functionality, such as:&lt;/p&gt;
&lt;pre&gt;namespace 'foo' do
  namespace 'bar' do
    desc "This task ..."
    task :baz do

    end
  end
end&lt;/pre&gt;
&lt;p&gt;Your task isn&amp;#8217;t instantly executable either. After each change, you need to uninstall the task (&lt;code&gt;sake -u foo:bar:baz&lt;/code&gt;) and then reinstall the sake file (&lt;code&gt;sake -i foo/bar/baz.sake&lt;/code&gt;) and then run it (&lt;code&gt;sake foo:bar:baz&lt;/code&gt;). Perhaps there&amp;#8217;s a way to inline edit a sake task, but I can&amp;#8217;t see it from the help options.&lt;/p&gt;
&lt;p&gt;But once you&amp;#8217;ve got your script installed in sake, you get all the wonders that sake provides: a named list (with summary) of tasks (&lt;code&gt;sake -T&lt;/code&gt;) and the ability to run those tasks anywhere. Ok, that&amp;#8217;s really only one advantage over standard Ruby scripts. But I like it. Oh, namespacing. The &lt;code&gt;baz&lt;/code&gt; task exists in a namespace &lt;code&gt;foo:bar&lt;/code&gt;. That&amp;#8217;s nice too.&lt;/p&gt;
&lt;p&gt;So to make me happy, I need a solution to the dubious &amp;#8220;create-install-execute&amp;#8221; process above. I also want the raw source for all my sake tasks in one place so I can fix/add/change them, reinstall them and move on with my life. I want simple.&lt;/p&gt;
&lt;p&gt;So I&amp;#8217;ve forked &lt;a href="http://ozmm.org/" target="_blank"&gt;Chris Wanstrath&lt;/a&gt;&amp;#8217;s empty &lt;a href="http://github.com/defunkt/sake-tasks/tree/master" target="_blank"&gt;sake-tasks&lt;/a&gt; repo (&lt;a href="http://github.com/drnic/sake-tasks/tree/master" target="_blank"&gt;mine&lt;/a&gt;) and added some infrastructure for managing sake tasks. Of course the repo itself is the repository for my sake tasks (which includes a lot from &lt;a href="http://www.lukemelia.com/" target="_blank"&gt;Luke Melia&lt;/a&gt;), but most importantly it has a single rake task to reinstall all the tasks without any manual fuss.&lt;/p&gt;
&lt;p&gt;The rest of this article assumes you want to have your own repository for your own sake tasks hosted on github. This paragraph is probably unnecessary, but I don&amp;#8217;t want to be accused of not being mildly thorough.&lt;/p&gt;
&lt;h3 id="fork_the_sake_tasks_repo"&gt;Fork the sake-tasks repo&lt;/h3&gt;
&lt;p&gt;For thoroughness and a chance to demonstrate some gold-medal git-fu, I&amp;#8217;ll show two ways: fork my repo and forking the original repo from Chris and pulling my stuff into yours. It&amp;#8217;s git, it&amp;#8217;s distributed, you can do anything.&lt;/p&gt;
&lt;p&gt;If you want to fork my repo and skip a nifty git lesson, go to my &lt;a href="http://github.com/drnic/sake-tasks/tree/master" target="_blank"&gt;sake-tasks&lt;/a&gt; repo and click &amp;#8220;fork&amp;#8221;. Then follow the clone instructions as you normally do when you are blatantly, systematically duplicating someone else&amp;#8217;s hard work, using a command that will look something like:&lt;/p&gt;
&lt;pre&gt;git clone git@github.com:your-github-username/sake-tasks.git&lt;/pre&gt;
&lt;p&gt;Now, lazy man, you can skip to the next step.&lt;/p&gt;
&lt;p&gt;If you want to flex your git-fu, then go and fork Chris&amp;#8217; &lt;a href="http://github.com/defunkt/sake-tasks/tree/master" target="_blank"&gt;repo&lt;/a&gt; instead. Again, follow the clone instructions. &lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.skitch.com/20080819-x6k16gsb4axearp6g5if6ntxs2.jpg" onload="resizeImage( this )" alt="empty repo from defunkt" /&gt;&lt;/p&gt;
&lt;p&gt;Now take a moment to reflect on just how empty your repository is. A fine moment in open-source where you&amp;#8217;ve essentially cloned an empty repository. Hardly worth the effort, but since Chris is a creator of github then if he creates an empty repository then who am I to disagree. Empty it shall start. &lt;/p&gt;
&lt;p&gt;Now let&amp;#8217;s pull in the code and tasks from my repo. My repo could be any git repo anywhere on the tubes. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://drnicwilliams.com/2008/02/03/using-git-within-a-team/" target="_blank"&gt;One way&lt;/a&gt; you could pull my code into your local repository is to add my repo as a remote and then pull in the goodness:&lt;/p&gt;
&lt;pre&gt;git remote add drnic git://github.com:drnic/sake-tasks.git
git pull drnic master&lt;/pre&gt;
&lt;p&gt;This is useful if you ever plan on re-pulling from a target repo again in the future.&lt;/p&gt;
&lt;p&gt;If you just want to pull from someone&amp;#8217;s repo one time only, then you can merge these two lines together:&lt;/p&gt;
&lt;pre&gt;git pull git://github.com:drnic/sake-tasks.git master&lt;/pre&gt;
&lt;p&gt;If you get occasional pull requests for your projects, then the latter option is handy to know.&lt;/p&gt;
&lt;p&gt;Your local repo is now different to your remote repo (your fork on github) so push it back to your remote:&lt;/p&gt;
&lt;pre&gt;git push origin master&lt;/pre&gt;
&lt;h3 id="installing_the_sake_tasks"&gt;Installing the sake tasks&lt;/h3&gt;
&lt;p&gt;I originally created my sake-tasks fork so I could store a &lt;a href="http://github.com/drnic/sake-tasks/tree/master/git/manpages/install.sake" target="_blank"&gt;git:manpages:install&lt;/a&gt; task. I&amp;#8217;ve just upgraded to git 1.6 (note to self: I want an &amp;#8216;upgrade to latest git version via src&amp;#8217; task) and found some &lt;a href="http://subtlegradient.com/articles/2008/02/21/install_git_leopard" target="_blank"&gt;instructions&lt;/a&gt; for installing the pre-built manpages. Then I got over excited and refactored all of Luke Melia&amp;#8217;s git+mysql+ssh tasks in to my repo so it looked like I&amp;#8217;d done a lot of work.&lt;/p&gt;
&lt;p&gt;To install all the tasks, first install sake:&lt;/p&gt;
&lt;pre&gt;sudo gem install sake&lt;/pre&gt;
&lt;p&gt;Then run the install task (check below for the list of tasks to be installed):&lt;/p&gt;
&lt;p&gt;WARNING: This will uninstall any tasks you already have by the same name.&lt;/p&gt;
&lt;pre&gt;rake install&lt;/pre&gt;
&lt;p&gt;Now, check that your sake tasks are installed:&lt;/p&gt;
&lt;pre&gt;sake -T&lt;/pre&gt;
&lt;p&gt;Gives you:&lt;/p&gt;
&lt;pre&gt;sake git:analyze:commits:flog_frequent   # Flog the most commonly revised files in the git history
sake git:close                           # Delete the current branch and switch back to master
sake git:manpages:install                # Install man pages for current git version
sake git:open                            # Create a new branch off master
sake git:pull                            # Pull new commits from the repository
sake git:push                            # Push all changes to the repository
sake git:status                          # Show the current status of the checkout
sake git:topic                           # Create a new topic branch
sake git:update                          # Pull new commits from the repository
sake mysql:dump                          # Dump the database to FILE (depends on mysql:params)
sake mysql:load                          # Load the database from FILE (depends on mysql:params)
sake ssh:install_public_key              # Install your public key on a remote server.&lt;/pre&gt;
&lt;p&gt;Sexy.&lt;/p&gt;
&lt;h3 id="adding_new_recipes_tasks"&gt;Adding new recipes/tasks&lt;/h3&gt;
&lt;p&gt;The installer rake task rake install works by assuming that each .sake file contains one sake task. This allows the rake task to uninstall the tasks from sake first, and then re-install it (sake barfs if you attempt to reinstall an existing task). Without the one-task-per-file rule, the solution would be to load all the sake tasks as rake tasks into memory. But I like one-task-per-file; it seems clean.&lt;/p&gt;
&lt;p&gt;So, to create a task &lt;code&gt;foo:bar:baz&lt;/code&gt;, you&amp;#8217;ll need to add a folder &lt;code&gt;foo/bar&lt;/code&gt; and create a file &lt;code&gt;baz.sake&lt;/code&gt; inside it. Within that file you would then specify your task using namespace and task method calls:&lt;/p&gt;
&lt;pre&gt;namespace 'foo' do
  namespace 'bar' do
    desc "This task ..."
    task :baz do

    end
  end
end
&lt;/pre&gt;
&lt;p&gt;To install new tasks or reinstall modified tasks, just run the rake task (&lt;code&gt;rake install&lt;/code&gt; or &lt;code&gt;rake&lt;/code&gt;).&lt;/p&gt;
&lt;h4 id="textmate_users"&gt;TextMate users&lt;/h4&gt;
&lt;p&gt;The latest &lt;a href="http://github.com/drnic/ruby-tmbundle" target="_blank"&gt;Ruby.tmbundle&lt;/a&gt; on github includes a task command that generates the above namespace/task snippet based on the path + file name. That is, inside the foo/bar/baz.sake file, make sure your grammar is &amp;#8216;Ruby&amp;#8217; or &amp;#8216;Ruby on Rails&amp;#8217; and then type &amp;#8220;task&amp;#8221; and press TAB. The above snippet will be generated ready for you to specify your task.&lt;/p&gt;
&lt;h3 id="summary"&gt;Summary&lt;/h3&gt;
&lt;p&gt;So now I have a single place for all my original sake source and a simple rake task to re-install the tasks if I add or modify them. And because its all in one git repo, if other people fork it and add their own tasks then I can steal them.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/DrNic?a=jqTmbk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/DrNic?i=jqTmbk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/DrNic?a=uX58ik" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/DrNic?i=uX58ik" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/DrNic?a=Jiconk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/DrNic?i=Jiconk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;</summary>
    <source>
      <id>http://drnicwilliams.com/?p=289</id>
      <link rel="alternate" href="http://drnicwilliams.com/2008/08/19/my-attempt-at-sake-task-management/"/>
      <title>My attempt at sake task management</title>
      <updated>2008-08-19T04:55:32+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Finding Good Rails Training in Your Area</title>
    <updated>2008-08-19T01:47:12+00:00</updated>
    <published>2008-08-19T01:25:00+00:00</published>
    <id>planetaki.com:905:post:6271639</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/368599172/finding-good-rails-training-in-your-area"/>
    <summary type="html">&lt;p&gt;I just wanted to take a quick moment to recognize the &lt;a href="http://www.rubyonrailsworkshops.com/" target="_blank"&gt;Ruby On Rails Workshops&lt;/a&gt; site.  It&#8217;s provided by &lt;a href="http://www.topfunky.com" target="_blank"&gt;Geoffrey Grosenbach&lt;/a&gt;.  It&#8217;s been around for as long as I can remember (ok, probably since 2006, I guess?), and always lists the top-notch events that are happening in the Ruby/Rails world.&lt;/p&gt;


	&lt;p&gt;I really like the way you can filter the results by country.  Or use the calendar to quickly get a monthly listing (and even hover over a date in the calendar to see what classes are on that day).&lt;/p&gt;


	&lt;p&gt;For example, here are &lt;a href="http://rubyonrailsworkshops.com/countries/show/228" target="_blank"&gt;the workshops coming up in the US&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Thanks to Geoffrey for continuing to maintaining the site and continuing to make it available as a service to the Ruby and Rails communities.&lt;/p&gt;


&lt;hr /&gt;
Ready to learn all about &lt;span class="caps"&gt;REST&lt;/span&gt; with Rails? Our next workshop is coming up fast (Oct 4, 2008), so &lt;a href="http://www.purpleworkshops.com/workshops/rest-and-web-services" target="_blank"&gt;register now&lt;/a&gt; before all the seats are taken.
          
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/SoftiesOnRails?a=23hzB4" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~a/SoftiesOnRails?i=23hzB4" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=fNFCCk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=fNFCCk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=NYtkMk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=NYtkMk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=Vf44NK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=Vf44NK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=yzue4K" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=yzue4K" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SoftiesOnRails/~4/368599172" height="1" onload="resizeImage( this )" width="1" /&gt;</summary>
    <source>
      <id>tag:www.softiesonrails.com,2008-08-19:26513</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/368599172/finding-good-rails-training-in-your-area"/>
      <title>Finding Good Rails Training in Your Area</title>
      <updated>2008-08-19T01:47:12+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Episode 123: Subdomains</title>
    <updated>2008-08-18T11:50:22+00:00</updated>
    <published>2008-08-18T07:00:00+00:00</published>
    <id>planetaki.com:905:post:6232241</id>
    <link rel="alternate" href="http://railscasts.com/episodes/123-subdomains"/>
    <summary type="html">Learn how to unleash the full potential of subdomains with the subdomain-fu Rails plugin in this episode.</summary>
    <source>
      <id>subdomains</id>
      <link rel="alternate" href="http://railscasts.com/episodes/123-subdomains"/>
      <title>Episode 123: Subdomains</title>
      <updated>2008-08-18T11:50:22+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Do Your Own (Ruby) Olympics</title>
    <updated>2008-08-18T05:46:40+00:00</updated>
    <published>2008-08-18T04:46:00+00:00</published>
    <id>planetaki.com:905:post:6217851</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/367799697/do-your-own-ruby-olympics"/>
    <summary type="html">&lt;p&gt;Suppose someone told you that they are an Olympic athlete.  What would you know about them? You could safely assume that they&#8217;re in great physical shape.  But you&#8217;d have to ask more questions: what kind of athlete are you?  Are you a swimmer?  A runner?  Maybe you do archery?&lt;/p&gt;


	&lt;p&gt;Even knowing the sport might not reveal all of their talents.  For example, many Olympic events have a variety of events associated with them.  To qualify for the swim team, you have to swim in multiple ways: freestyle, butterfly, backstroke, and breast stroke.  Gymnasts also have to be good at a lot of things to be considered Olympic material: not only the floor exercise, but also the pommel horse, vault, and rings, and I don&#8217;t know what else.&lt;/p&gt;


	&lt;p&gt;Swimmers who only excel at freestyle swimming might be great at freestyle swimming, but they&#8217;ll never really be able to be good enough to make the Olympic team.  Gymnasts who are great at the pommel horse, but never bother to learn the other disciplines, won&#8217;t make the team either.&lt;/p&gt;


	&lt;h2&gt;Umm&#8230; Isn&#8217;t This Blog About Rails?&lt;/h2&gt;


	&lt;p&gt;Ok, I&#8217;m getting to the point&#8230; Perhaps you currently consider yourself to be a real cool Rails developer.  But do you really take the time to learn all of different skills that entails?&lt;/p&gt;


	&lt;p&gt;If there was a Rails event at the Olympics, would you qualify?&lt;/p&gt;


	&lt;p&gt;Here are the main &#8220;events&#8221; that I think Rails developers need to be good at to be considered &#8220;Olympic&#8221; quality.&lt;/p&gt;


	&lt;h2&gt;Ruby&lt;/h2&gt;


	&lt;p&gt;First and foremost, how is your Ruby?  When was the last time you learned something new about Ruby?  I don&#8217;t mean Rails.  I mean &lt;em&gt;Ruby&lt;/em&gt;.  If you haven&#8217;t been able to refactor your code into something simpler and clearer, then you probably need to spend more time with the Ruby language.&lt;/p&gt;


	&lt;h2&gt;ActiveRecord&lt;/h2&gt;


	&lt;p&gt;ActiveRecord has actually gotten pretty big.  Some features may exist that you don&#8217;t know about, or don&#8217;t know how to use (&lt;code&gt;has_many :through&lt;/code&gt; and &lt;code&gt;named_scope&lt;/code&gt; come to mind).  Learn them.  Use them.  They can simplify your code.  Not sure about the difference between association proxies and arrays?  Wondering what &lt;span class="caps"&gt;SQL&lt;/span&gt; calls ActiveRecord is really making on your behalf?  Then it&#8217;s time to do some strength conditioning and learn more about it.&lt;/p&gt;


	&lt;h2&gt;Views&lt;/h2&gt;


	&lt;p&gt;Maybe you&#8217;re feeling pretty good with your &lt;span class="caps"&gt;HTML&lt;/span&gt; views.  How about your Javascript skills?  Are you using the best possible &lt;code&gt;form_for&lt;/code&gt; syntax in your views?  Have you learned how to use view helpers to &lt;span class="caps"&gt;DRY&lt;/span&gt; up your view code?&lt;/p&gt;


	&lt;h2&gt;&lt;span class="caps"&gt;SQL&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;Just because ActiveRecord writes &lt;span class="caps"&gt;SQL&lt;/span&gt; for you doesn&#8217;t mean you don&#8217;t have to learn &lt;span class="caps"&gt;SQL&lt;/span&gt;.  It&#8217;s a muscle that we Rails developers can avoid using, but that probably mean that it&#8217;s atrophied.  I know for myself, &lt;span class="caps"&gt;SQL&lt;/span&gt; is probably my weakest link when it comes to Rails development.  I need to spend more time in the &lt;span class="caps"&gt;SQL&lt;/span&gt; gym, so I can better understand and improve upon the database performance in my apps.&lt;/p&gt;


	&lt;h2&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;If you&#8217;re not doing RESTful development, but you&#8217;re using Rails 1.2 or higher, then you really need to get on the ball. Or maybe you think you&#8217;ve got the RESTful thing down pat, but you still end up adding a bunch of custom actions to your controllers.  If so, then it&#8217;s time to see &lt;a href="http://www.purpleworkshops.com/workshops/rest-and-web-services" target="_blank"&gt;your friendly neighborhood trainer&lt;/a&gt; and get your &lt;span class="caps"&gt;REST&lt;/span&gt; skills in shape.  Your apps (and your boss) will thank you.&lt;/p&gt;


	&lt;h2&gt;Anything Else&lt;/h2&gt;


	&lt;p&gt;You probably feel a twinge of guilt about some area of Rails that you know you should get better at, but you just never seem to have the time.  Do you know how to write a plugin?  Do you know how to contribute a patch to Rails?  Do you need to get better with subversion or git? How about deployment?  The list could go on and on.&lt;/p&gt;


	&lt;p&gt;If you want to say you&#8217;re a professional Rails developer, you can&#8217;t just be good at &lt;code&gt;script/generate model Product&lt;/code&gt;.  Identify what you want to learn next, and learn it.&lt;/p&gt;


	&lt;p&gt;Have you learned something recently that really helped you get to the next level in your Rails coding?  Or, is there a weak area that you know you want to get better at?  Drop us a comment and let us know.&lt;/p&gt;


&lt;hr /&gt;
Ready to learn all about &lt;span class="caps"&gt;REST&lt;/span&gt; with Rails? Our next workshop is coming up fast (Oct 4, 2008), so &lt;a href="http://www.purpleworkshops.com/workshops/rest-and-web-services" target="_blank"&gt;register now&lt;/a&gt; before all the seats are taken.
          
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/SoftiesOnRails?a=tQoYp6" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~a/SoftiesOnRails?i=tQoYp6" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=jM5rSk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=jM5rSk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=wm5Hbk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=wm5Hbk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=1Z67FK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=1Z67FK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=vxqLUK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=vxqLUK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SoftiesOnRails/~4/367799697" height="1" onload="resizeImage( this )" width="1" /&gt;</summary>
    <source>
      <id>tag:www.softiesonrails.com,2008-08-18:26499</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/367799697/do-your-own-ruby-olympics"/>
      <title>Do Your Own (Ruby) Olympics</title>
      <updated>2008-08-18T05:46:40+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Sorting things out</title>
    <updated>2008-08-17T18:05:23+00:00</updated>
    <published>2008-08-17T17:49:28+00:00</published>
    <id>planetaki.com:905:post:6197847</id>
    <link rel="alternate" href="http://blog.hasmanythrough.com/2008/8/17/sorting-things-out"/>
    <summary type="html">&lt;p&gt;I recently packed up everything I own and moved.  I'd lived in my old place for about nine years and I have the packrat gene on both sides of the family tree, so I had a lot of crap to sort through to figure out what to move and what to trash, as well as which box what should go in.  Now that I'm here in the new place, I've had to sort through the remaining stuff to figure out where it all goes.  So you might appreciate that sorting has been on my mind a lot lately.  (See?  It's a topical tie-in.  I don't do those often, so I hope it wasn't too awkward.)&lt;/p&gt;

&lt;p&gt;I've also been working on an application that does a lot of sorting to prioritize tasks in a workflow.  These items often need to be sorted based on multiple criteria, such as how long an application has been waiting for approval, how many times a customer has been called recently, etc.  We also have to sort names that have anywhere from two to four components (Hispanic names can have both paternal and maternal names instead of just a surname).&lt;/p&gt;

&lt;p&gt;Ruby enumerables can be sorted using the &lt;code&gt;#sort&lt;/code&gt; method, which orders contents using the &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; trinary comparison operator.  It's pretty simple to override &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; if instances of a class are only ever sorted one way, but when you get to a situation where you need to sort things in different ways depending on the context, you need a more flexible solution&lt;/p&gt;

&lt;p&gt;The next obvious thing to try is passing a block to the #sort method.  This works great, but it has two drawbacks.  One, if the sort criteria are complex, you can end up with some ugly looking code.  And B, it's not very DRY for re-using sort criteria.&lt;/p&gt;

&lt;p&gt;The approach I came up with for my application makes use of the sorting properties of Ruby arrays.  Ruby arrays sort quite nicely using the &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; operator.  &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; compares two arrays by comparing all their values until a non-equal result is found for any pairings of values in the two arrays.  Here are some example comparisons:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; [1, 2, 3] &amp;lt;=&amp;gt; [1, 2, 3]
=&amp;gt; 0
&amp;gt;&amp;gt; [0, 2, 3] &amp;lt;=&amp;gt; [1, 2, 3]
=&amp;gt; -1
&amp;gt;&amp;gt; [1, 2, 3] &amp;lt;=&amp;gt; [0, 2, 3]
=&amp;gt; 1
&amp;gt;&amp;gt; [1, 2, [4, 5]] &amp;lt;=&amp;gt; [1, 2, [6, 7]]
=&amp;gt; -1
&amp;gt;&amp;gt; [1, 2, [4, 5]] &amp;lt;=&amp;gt; [1, 2, [2, 3]]
=&amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are some things to watch out for, like don't have nil anywhere in the array contents, and shorter arrays sort less than longer arrays where all else is equal.  But this is a great feature to build upon.&lt;/p&gt;

&lt;p&gt;Based on the array sorting functionality, I defined a concept I call a &lt;em&gt;sorter&lt;/em&gt;.  A sorter is an array that holds multiple values to use to sort the collection by in order of precedence.  For example, if you want to sort people by name using the precedence &lt;em&gt;paternal, maternal, first, middle&lt;/em&gt;, you can construct an array of those values and sort the list using that.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Person &amp;lt; ActiveRecord::Base
  def name_sorter
    [(paternal_name || ""), (maternal_name || ""), (first_name || ""), (middle_name || "")]
  end
end

@people = Person.find(:all).sort_by { |p| p.name_sorter }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice I'm making sure that I never have a nil as a value in the sorter, cause that will make things blow up like the ending of a Die Hard movie.  If you want to avoid that verbiage, set up the model so that the names default to empty strings.  Also notice that I'm using the &lt;code&gt;#sort_by&lt;/code&gt; method, instead of the &lt;code&gt;#sort&lt;/code&gt; method with a 2-arg block.  Actually, let's look at all our options.  The following three forms will give equivalent results:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@people = Person.find(:all).sort_by { |p| p.name_sorter }
@people = Person.find(:all).sort_by(&amp;amp;:name_sorter)
@people = Person.find(:all).sort { |a,b| a.name_sorter &amp;lt;=&amp;gt; b.name_sorter }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first line is the one I'd use in most situations.  The second line is slightly more compact, but the symbol-to-proc coercion should be avoided in any code where you care about performance (at least until Ruby 1.9 is ready for prime time).  The third line is usually going to be a bad choice, because a sorter array would be created for every time its person was compared, which will be roughly ln(n) times if you are willing to believe my naive assumptions about Ruby's sorting algorithm.  If you don't want to trust naivet&#233;, check out the simple performance comparison I ran.  This benchmark sorts an array of 60 items using a sorter on 4 values.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;                user     system      total        real
sort        6.430000   0.000000   6.430000 (  6.466645)
sort_by     1.510000   0.000000   1.510000 (  1.509017)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That kind of difference is pretty significant to me.  Of course, if your sorter can be cached so you can reuse it for multiple comparisons, a #sort might be better.  As always, measure it if you care and you're not sure.&lt;/p&gt;

&lt;p&gt;One last thing. What if we just rolled the sort by hand using a block?  (The code below assumes names will default to an empty string.)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@people = Person.find(:all).sort do |a,b|
  if    0 != (comp = a.last_name &amp;lt;=&amp;gt; b.last_name)
    comp
  elsif 0 != (comp = a.maternal_name &amp;lt;=&amp;gt; b.maternal_name)
    comp
  elsif 0 != (comp = a.first_name &amp;lt;=&amp;gt; b.first_name)
    comp
  else
    a.middle_name &amp;lt;=&amp;gt; b.middle_name
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's fairly ugly and it's actually slower than the &lt;code&gt;#sort_by&lt;/code&gt; approach too.  &lt;/p&gt;

&lt;p&gt;And because I don't believe in secret benchmarks, here is a gist of &lt;a href="http://gist.github.com/5812" target="_blank"&gt;the benchmark code&lt;/a&gt; I used.&lt;/p&gt;

&lt;p&gt;Now if you'll excuse me, I have a lot of empty cardboard boxes to toss in the recycling.&lt;/p&gt;</summary>
    <source>
      <id>tag:blog.hasmanythrough.com,2006-02-27:Article/116</id>
      <link rel="alternate" href="http://blog.hasmanythrough.com/2008/8/17/sorting-things-out"/>
      <title>Sorting things out</title>
      <updated>2008-08-17T18:05:23+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Josh Peek officially joins the Rails core</title>
    <updated>2008-08-19T04:38:59+00:00</updated>
    <published>2008-08-16T20:03:00+00:00</published>
    <id>planetaki.com:905:post:6166270</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/RidingRails/~3/366749012/josh-peek-officially-joins-the-rails-core"/>
    <summary type="html">&lt;p&gt;Josh Peek has been a defacto Rails core committer for a while, but for some reason we&#8217;ve never actually made the appointment official. So here it goes: &lt;a href="http://www.rubyonrails.org/core" target="_blank"&gt;Josh Peek is the latest Rails core team member&lt;/a&gt;. Three cheers hurray!&lt;/p&gt;


	&lt;p&gt;Josh has been working on a Google Summer of Code project to bring thread safety to Rails and is just about ready to wrap it up. Rails 2.2 will be thread safe thanks to the work that Josh has put into it.&lt;/p&gt;


	&lt;p&gt;Of more importance, though, is the significant effort put into making things faster and cleaner as part of that push. The actual thread safety won&#8217;t really matter much to most people, but it&#8217;ll surely look nice on your enterprisey check list of Features Your Framework Must Have To Get Play Around Here.&lt;/p&gt;


	&lt;p&gt;In any case, please welcome Josh!&lt;/p&gt;</summary>
    <source>
      <id>tag:weblog.rubyonrails.com,2008-08-16:21266</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/RidingRails/~3/366749012/josh-peek-officially-joins-the-rails-core"/>
      <title>Josh Peek officially joins the Rails core</title>
      <updated>2008-08-19T04:38:59+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Cloning Ubuntu Hardy image in VMWare Fusion</title>
    <updated>2008-08-15T23:40:03+00:00</updated>
    <published>2008-08-15T22:50:00+00:00</published>
    <id>planetaki.com:905:post:6130963</id>
    <link rel="alternate" href="http://weblog.jamisbuck.org/2008/8/15/cloning-ubuntu-hardy-image-in-vmware-fusion"/>
    <summary type="html">&lt;p&gt;Having spent the better part of a day googling and struggling, I figured it would possibly benefit others if I took a minute to post the steps I took to clone a VMWare Fusion image. The image in question is of Ubuntu Server (Hardy). I&#8217;m using VMWare Fusion 2 (beta 2).&lt;/p&gt;


	&lt;p&gt;Just find your &#8220;Virtual Machines&#8221; folder (should be in your Documents folder), and copy the image in question to a new location. (The images are actually folders; a simple &#8220;cp -R&#8221; worked fine for me.)&lt;/p&gt;


	&lt;p&gt;Then, open the copied image in VMWare Fusion and boot it. VMWare Fusion will ask if you if you copied or moved the image&#8212;be sure to say you copied it (that let&#8217;s VMWare set up a new &lt;span class="caps"&gt;MAC&lt;/span&gt; address for your image).&lt;/p&gt;


	&lt;p&gt;Go ahead and log in once the server boots. You&#8217;ll find networking is all hosed. To fix networking, this worked for me:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&#8220;sudo hostname blah&#8221;, to set the hostname. This doesn&#8217;t change it permanently, so you&#8217;ll also want to:&lt;/li&gt;
		&lt;li&gt;&#8220;sudo vim /etc/hostname&#8221;. Change the contents of the file to the hostname you want. Then:&lt;/li&gt;
		&lt;li&gt;&#8220;sudo vim /etc/hosts&#8221;. Replace all mentions of the old hostname with the new hostname.&lt;/li&gt;
		&lt;li&gt;&#8220;sudo vim /etc/udev/rules.d/70-persistent-net.rules&#8221;. There will be two entries in this file. The first points eth0 at the old &lt;span class="caps"&gt;MAC&lt;/span&gt; address, and the second points eth1 at the new. Go ahead and delete the first entry, and change &#8220;eth1&#8221; to &#8220;eth0&#8221; in the second (and now only) entry.&lt;/li&gt;
		&lt;li&gt;&#8220;sudo shutdown -r now&#8221; to restart your virtual machine.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Once your machine comes back up, you should have a network again! Now, if only VMWare Fusion could bake all this in somehow&#8230; :/&lt;/p&gt;


	&lt;p&gt;(Related: &lt;a href="http://www.gorillapond.com/2006/07/31/install-vmware-tools-on-ubuntu/" target="_blank"&gt;installing VMWare Tools on Ubuntu server&lt;/a&gt;. It&#8217;s from 2006, but it still worked well enough for me, though I followed the instructions for tweaking the network that the VMWare Tools install gave at the end, rather than what this gent said.)&lt;/p&gt;</summary>
    <source>
      <id>tag:weblog.jamisbuck.org,2008-08-15:4665</id>
      <link rel="alternate" href="http://weblog.jamisbuck.org/2008/8/15/cloning-ubuntu-hardy-image-in-vmware-fusion"/>
      <title>Cloning Ubuntu Hardy image in VMWare Fusion</title>
      <updated>2008-08-15T23:40:03+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Ruby on Rails Google Group Getting Better</title>
    <updated>2008-08-14T21:32:30+00:00</updated>
    <published>2008-08-14T20:45:00+00:00</published>
    <id>planetaki.com:905:post:6072002</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/365092622/ruby-on-rails-google-group-getting-better"/>
    <summary type="html">&lt;p&gt;&lt;a href="http://www.spacevatican.org/" target="_blank"&gt;Frederick Cheung&lt;/a&gt; has done a great job eliminating the spam problem that had been plaguing the &lt;a href="http://groups.google.com/group/rubyonrails-talk" target="_blank"&gt;Ruby on Rails Google Group&lt;/a&gt;.  I had more or less abandoned the group months ago, because the value of the group had plummeted.&lt;/p&gt;


	&lt;p&gt;But lately I&#8217;ve enjoyed posting questions and answers there again.  If you have never tried the Google Group (also mirrored &lt;a href="http://www.ruby-forum.com/forum/3" target="_blank"&gt;here&lt;/a&gt; if you prefer a different UI than Google&#8217;s), I recommend it.&lt;/p&gt;


	&lt;p&gt;Thanks to Frederick for volunteering his time and energy to serve the Rails community this way.&lt;/p&gt;


&lt;hr /&gt;
&lt;i&gt;New to &lt;span class="caps"&gt;REST&lt;/span&gt; in Rails?  Join us at &lt;a href="http://www.purpleworkshops.com/workshops/rest-and-web-services" target="_blank"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt; with Rails&lt;/a&gt; Oct 4, 2008, in Austin, TX&lt;/i&gt;
          
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/SoftiesOnRails?a=VFjy4b" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~a/SoftiesOnRails?i=VFjy4b" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=BhQA6k" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=BhQA6k" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=HS5spk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=HS5spk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=ymFygK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=ymFygK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=MSoU5K" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=MSoU5K" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SoftiesOnRails/~4/365092622" height="1" onload="resizeImage( this )" width="1" /&gt;</summary>
    <source>
      <id>tag:www.softiesonrails.com,2008-08-14:26422</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/365092622/ruby-on-rails-google-group-getting-better"/>
      <title>Ruby on Rails Google Group Getting Better</title>
      <updated>2008-08-14T21:32:30+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Tutorial #2: Recap</title>
    <updated>2008-08-14T21:32:13+00:00</updated>
    <published>2008-08-14T20:33:00+00:00</published>
    <id>planetaki.com:905:post:6071962</id>
    <link rel="alternate" href="http://weblog.jamisbuck.org/2008/8/14/tutorial-2-recap"/>
    <summary type="html">&lt;p&gt;So, the second Capistrano tutorial session has come and gone. It was a great session, though it started pretty rough. (I was very unprepared for some windows-related configuration issues during the first half-hour. That won&#8217;t happen again.) I appreciate everyone&#8217;s patience who participated!&lt;/p&gt;


	&lt;p&gt;I&#8217;m going to be quiet on the tutorial front for the next several weeks, but its not because I&#8217;ve given up on them. I&#8217;m going to be rethinking some aspects of them. I really want these to be opportunities for people to master capistrano, and while these first two tutorials have been very useful to those who attended (their words, not mine), I think they could be even better.&lt;/p&gt;


	&lt;p&gt;Stay tuned!&lt;/p&gt;</summary>
    <source>
      <id>tag:weblog.jamisbuck.org,2008-08-14:4663</id>
      <link rel="alternate" href="http://weblog.jamisbuck.org/2008/8/14/tutorial-2-recap"/>
      <title>Tutorial #2: Recap</title>
      <updated>2008-08-14T21:32:13+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>What's New in Edge Rails: Simpler Conditional Get Support (ETags)</title>
    <updated>2008-08-14T01:12:27+00:00</updated>
    <published>2008-08-14T00:32:00+00:00</published>
    <id>planetaki.com:905:post:6017017</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/RyansScraps/~3/364348231/what-s-new-in-edge-rails-simpler-conditional-get-support-etags"/>
    <summary type="html">&lt;p&gt;Conditional-gets are a facility of the &lt;span class="caps"&gt;HTTP&lt;/span&gt; spec that provide a way for web servers to tell browsers that the response to a &lt;code&gt;GET&lt;/code&gt; request hasn&#8217;t changed since the last request and can be safely pulled from the browser cache.&lt;/p&gt;


	&lt;p&gt;They work by using the &lt;code&gt; HTTP_IF_NONE_MATCH&lt;/code&gt; and &lt;code&gt; HTTP_IF_MODIFIED_SINCE&lt;/code&gt; headers to pass back and forth both a unique content identifier and the timestamp of when the content was last changed.  If the browser makes a request where the content identifier (etag) or last modified since timestamp matches the server&#8217;s version then the server only needs to send back an empty response with a not modified status.&lt;/p&gt;


	&lt;p&gt;It is the server&#8217;s (i.e. our) responsibility to look for a last modified timestamp and the if-none-match header and determine whether or not to send back the full response.  With &lt;a href="http://github.com/JackDanger/rails/commit/b7529ed1cc7cfd8df5fd1b069e2881d39d3d984c" target="_blank"&gt;this new conditional-get support in rails&lt;/a&gt; this is a pretty easy task:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ArticlesController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@article&lt;/span&gt; = &lt;span class="co"&gt;Article&lt;/span&gt;.find(params[&lt;span class="sy"&gt;:id&lt;/span&gt;])&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# Set the response headers to accurately reflect the state of the&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# requested object(s)&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    response.last_modified = &lt;span class="iv"&gt;@article&lt;/span&gt;.published_at.utc&lt;tt&gt;
&lt;/tt&gt;    response.etag = &lt;span class="iv"&gt;@article&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# If the request's state is the same as the server's state then we know&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# we don't have to send back the whole body&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;if&lt;/span&gt; request.fresh?(response)&lt;tt&gt;
&lt;/tt&gt;      head &lt;span class="sy"&gt;:not_modified&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      respond_to &lt;span class="r"&gt;do&lt;/span&gt; |wants|&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="c"&gt;# normal response processing&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The etag value is calculated for you with the &lt;code&gt;etag=&lt;/code&gt; setter method.  All you have to do is provide a single object or array of objects that uniquely identify this request.  In this example the article itself contains all the information that uniquely identifies the state of this request.  However, you may need to use more than one key in your app.  For instance, if the request is user specific:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;response.etag = [&lt;span class="iv"&gt;@article&lt;/span&gt;, current_user]&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The &lt;code&gt;request.fresh?(response)&lt;/code&gt; method is what will then tell you if the incoming request matches either the last-modified-since or if-none-match values of the outgoing response.  If it does you can avoid passing the full body of the response back and save some bandwidth.&lt;/p&gt;


	&lt;p&gt;It&#8217;s also possible that you can avoid hitting the database all together if your application deals with completely static resources (though this is rare):&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ArticlesController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;show&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# If articles don't change, the etag can be based solely&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# on items we have in the request&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    response.etag = [&lt;span class="sy"&gt;:article&lt;/span&gt;, params[&lt;span class="sy"&gt;:id&lt;/span&gt;]]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# If the request's state is the same as the server's state then we can&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# avoid the db call all together&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;if&lt;/span&gt; request.fresh?(response)&lt;tt&gt;
&lt;/tt&gt;      head &lt;span class="sy"&gt;:not_modified&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="iv"&gt;@article&lt;/span&gt; = &lt;span class="co"&gt;Article&lt;/span&gt;.find(params[&lt;span class="sy"&gt;:id&lt;/span&gt;])&lt;tt&gt;
&lt;/tt&gt;      respond_to &lt;span class="r"&gt;do&lt;/span&gt; |wants|&lt;tt&gt;
&lt;/tt&gt;        ...&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;So be a good citizen and make your requests conditional-get compatible.  It&#8217;s the right thing to do &#8211; and can make your apps more performant.&lt;/p&gt;


	&lt;p&gt;tags: &lt;a href="http://technorati.com/tag/ruby" target="_blank"&gt;ruby&lt;/a&gt;,
&lt;a href="http://technorati.com/tag/rubyonrails" target="_blank"&gt;rubyonrails&lt;/a&gt;&lt;/p&gt;
          
&lt;p&gt;&lt;map name="google_ad_map_DJ7vTzHf24yc92-LjXklhcNABK4_"&gt;&lt;area href="http://imageads.googleadservices.com/pagead/imgclick/DJ7vTzHf24yc92-LjXklhcNABK4_?pos=0" shape="rect" coords="1,2,367,28" /&gt;&lt;area href="http://services.google.com/feedback/abg" shape="rect" coords="384,10,453,23" /&gt;&lt;/map&gt;&lt;img src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=ca-pub-5311481257402216&amp;channel=7127926294&amp;output=png&amp;cuid=DJ7vTzHf24yc92-LjXklhcNABK4_&amp;url=http%3A%2F%2Fryandaigle.com%2Farticles%2F2008%2F8%2F14%2Fwhat-s-new-in-edge-rails-simpler-conditional-get-support-etags" border="0" onload="resizeImage( this )" usemap="http://ryandaigle.com/#google_ad_map_DJ7vTzHf24yc92-LjXklhcNABK4_" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RyansScraps?a=eGLVPS" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~a/RyansScraps?i=eGLVPS" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RyansScraps?a=GEZKdK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/RyansScraps?i=GEZKdK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RyansScraps?a=ZGPETK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/RyansScraps?i=ZGPETK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RyansScraps?a=7FhUtK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/RyansScraps?i=7FhUtK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RyansScraps?a=Gfdzjk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/RyansScraps?i=Gfdzjk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;</summary>
    <source>
      <id>tag:ryandaigle.com,2008-08-14:7345</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/RyansScraps/~3/364348231/what-s-new-in-edge-rails-simpler-conditional-get-support-etags"/>
      <title>What's New in Edge Rails: Simpler Conditional Get Support (ETags)</title>
      <updated>2008-08-14T01:12:27+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Charlas sobre Ruby y Shoes en Volcanica</title>
    <updated>2008-08-12T11:51:57+00:00</updated>
    <published>2008-08-12T11:05:11+00:00</published>
    <id>planetaki.com:905:post:5917598</id>
    <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/12/charlas-sobre-ruby-y-shoes-en-volcanica/"/>
    <summary type="html">&lt;p&gt;&lt;img title="shoes-logo" src="http://www.jaimeiniesta.com/wp-content/uploads/2008/08/shoes-logo.png" height="122" onload="resizeImage( this )" alt="" align="right" width="190" /&gt;&lt;a href="http://www.jaimeiniesta.com/2007/09/24/dos-talleres-de-ruby-on-rails-en-olot-para-el-20-de-octubre/" target="_blank"&gt;El a&#241;o pasado d&#237; un par de charlas sobre Rails en el evento Volcanica&lt;/a&gt;, y para la edici&#243;n de este a&#241;o (19, 20 y 21 de septiembre) me apetece centrarme m&#225;s en Ruby&amp;#8230;&lt;/p&gt;
&lt;p&gt;Estas son mis propuestas para este a&#241;o, una sobre introducci&#243;n a Ruby y otra sobre Shoes, el toolkit para aplicaciones de escritorio con Ruby que me est&#225; divirtiendo tant&#237;simo &#250;ltimamente.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;####################&lt;br /&gt;
&lt;/strong&gt; &lt;strong&gt;1.- Programaci&#243;n en Ruby&lt;br /&gt;
####################&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ruby es un lenguaje de programaci&#243;n din&#225;mico y de c&#243;digo abierto enfocado en la simplicidad y productividad, entre cuyos principios de dise&#241;o est&#225; el maximizar la felicidad del programador haci&#233;ndole la vida m&#225;s f&#225;cil.&lt;/p&gt;
&lt;p&gt;En este taller daremos un repaso a la sintaxis de Ruby, con ejemplos pr&#225;cticos de programaci&#243;n y de uso de algunas de las librer&#237;as m&#225;s interesantes de que dispone el lenguaje.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.ruby-lang.org/es/about/" target="_blank"&gt;http://www.ruby-lang.org/es/about/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;###############################&lt;br /&gt;
&lt;/strong&gt; &lt;strong&gt;2.- Shoes, programaci&#243;n gr&#225;fica con Ruby&lt;br /&gt;
###############################&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El lenguaje de programaci&#243;n Ruby no est&#225; limitado al desarrollo web y scripts de mantenimiento, sino que puede ser empleado tambi&#233;n para la programaci&#243;n de aplicaciones de escritorio con interfaz gr&#225;fica basada en ventanas.&lt;/p&gt;
&lt;p&gt;Shoes es un toolkit que nos permite programar aplicaciones de ventanas multiplataforma con muy pocas l&#237;neas de c&#243;digo, empleando Ruby. Adem&#225;s sus capacidades para gr&#225;ficos, animaciones, y audio nos permiten programar juegos y demos.&lt;/p&gt;
&lt;p&gt;Las posibilidades de Shoes y la sencillez de su sintaxis lo hace muy apropiado para ense&#241;ar a programar a ni&#241;os, as&#237; como a los adultos que echamos de menos los a&#241;os dorados del ZX Spectrum &lt;img class="wp-smiley" src="http://www.jaimeiniesta.com/wp-includes/images/smilies/icon_smile.gif" onload="resizeImage( this )" alt=":)" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.whytheluckystiff.net/shoes" target="_blank"&gt;http://code.whytheluckystiff.net/shoes&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.the-shoebox.org/" target="_blank"&gt; http://www.the-shoebox.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;M&#225;s informaci&#243;n sobre el evento Volcanica en:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.volcanica.cat" target="_blank"&gt;http://www.volcanica.cat&lt;/a&gt;&lt;/p&gt;</summary>
    <source>
      <id>http://www.jaimeiniesta.com/?p=177</id>
      <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/12/charlas-sobre-ruby-y-shoes-en-volcanica/"/>
      <title>Charlas sobre Ruby y Shoes en Volcanica</title>
      <updated>2008-08-12T11:51:57+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Episode 122: Passenger in Development</title>
    <updated>2008-08-11T11:43:38+00:00</updated>
    <published>2008-08-11T07:00:00+00:00</published>
    <id>planetaki.com:905:post:5855875</id>
    <link rel="alternate" href="http://railscasts.com/episodes/122-passenger-in-development"/>
    <summary type="html">Tired of juggling multiple Rails apps around with script/server? See how to set up Passenger in development so each one has its own local domain name.</summary>
    <source>
      <id>passenger-in-development</id>
      <link rel="alternate" href="http://railscasts.com/episodes/122-passenger-in-development"/>
      <title>Episode 122: Passenger in Development</title>
      <updated>2008-08-11T11:43:38+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>REST with Rails: Registration Now Open</title>
    <updated>2008-08-10T15:26:27+00:00</updated>
    <published>2008-08-10T14:53:00+00:00</published>
    <id>planetaki.com:905:post:5816408</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/361134543/rest-with-rails-registration-now-open"/>
    <summary type="html">&lt;p&gt;&lt;strong&gt;Registration is officially now open for &lt;a href="http://www.purpleworkshops.com/workshops/rest-and-web-services" title="REST with Rails" target="_blank"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt; with Rails&lt;/a&gt;, coming to Austin, Texas on Saturday, October 4, 2008.&lt;/strong&gt;&lt;/p&gt;


&lt;hr /&gt;
&lt;strong&gt;&lt;a href="http://www.purpleworkshops.com/workshops/rest-and-web-services" target="_blank"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt; with Rails&lt;/a&gt;&lt;/strong&gt;

	&lt;p&gt;When: Saturday, October 4, 2008, 8:30am &#8211; 5:00pm&lt;/p&gt;


	&lt;p&gt;Where: FiveRuns Offices: 209 West 9th Street, Suite 100, Austin, Texas 78701&lt;/p&gt;


Cost: $295.00
&lt;hr /&gt;

	&lt;p&gt;If you&#8217;re new to &lt;span class="caps"&gt;REST&lt;/span&gt; and want to learn what all the fuss is about, join us for a fun, one-day workshop! We&#8217;ll cover all the basics of RESTful development with Rails. This class is geared for those new to &lt;span class="caps"&gt;REST&lt;/span&gt;, regardless of how long you&#8217;ve been using Rails.  (We assume you can at least create a simple Rails app, but not much more than that.)&lt;/p&gt;


	&lt;p&gt;All of our workshops have a friendly atmosphere.  There really are no dumb questions.  We use an informative combination of slides and live coding demos instead of long, boring powerpoint presentations.&lt;/p&gt;


	&lt;p&gt;And, thanks to &lt;a href="http://fiveruns.com" title="FiveRuns" target="_blank"&gt;FiveRuns&lt;/a&gt;, this public workshop will be held at their brand new offices in downtown Austin, Texas!&lt;/p&gt;


	&lt;p&gt;Seating is quite limited, so &lt;a href="http://www.purpleworkshops.com/workshops/rest-and-web-services" title="REST with Rails" target="_blank"&gt;read all about it&lt;/a&gt; and then &lt;a href="http://restwithrails.eventbrite.com" title="Sign Up" target="_blank"&gt;sign up&lt;/a&gt;!&lt;/p&gt;


	&lt;p&gt;(Those who signed up for early notification should have received your discount code.  If for some reason you didn&#8217;t get it, please let us know.)&lt;/p&gt;


	&lt;p&gt;Thanks, and we hope to see you there!&lt;/p&gt;
          
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/SoftiesOnRails?a=ahuNFr" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~a/SoftiesOnRails?i=ahuNFr" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=quDsqk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=quDsqk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=ar27mk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=ar27mk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=qsuyxK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=qsuyxK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=Z6qsxK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=Z6qsxK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SoftiesOnRails/~4/361134543" height="1" onload="resizeImage( this )" width="1" /&gt;</summary>
    <source>
      <id>tag:www.softiesonrails.com,2008-08-10:26343</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/361134543/rest-with-rails-registration-now-open"/>
      <title>REST with Rails: Registration Now Open</title>
      <updated>2008-08-10T15:26:27+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Conversi&#243;n de moneda con Google y Ruby</title>
    <updated>2008-08-19T17:10:27+00:00</updated>
    <published>2008-08-07T12:57:11+00:00</published>
    <id>planetaki.com:905:post:5662750</id>
    <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/07/conversion-de-moneda-con-google-y-ruby/"/>
    <summary type="html">&lt;p&gt;Tras leer esta idea de Albert Coronado para &lt;a href="http://blog.lostsys.com/?p=229" target="_blank"&gt;convertir moneda con Google y PHP&lt;/a&gt;, se me ha ocurrido probar a hacer lo mismo con Ruby, y este es el resultado:&lt;/p&gt;
&lt;pre lang="ruby"&gt;require 'open-uri'

class ConversorMonedaGoogle

  def self.euro_a_dolar
    google = open("http://google.es/search?q=1+Euro+to+%24").read
    pos_euro = google.index("1 Euro = ")
    pos_dolar = google.index("US$")

    google[pos_euro+9 .. pos_dolar-2]
  end

end

# Llamada de prueba...
puts "El euro est&#225; hoy a #{ConversorMonedaGoogle.euro_a_dolar} d&#243;lares seg&#250;n Google"&lt;/pre&gt;
&lt;p&gt;B&#225;sicamente, usamos la librer&#237;a est&#225;ndar open-uri para leer los resultados de buscar en Google &amp;#8220;1 Euro to $&amp;#8221;, y despu&#233;s buscamos el resultado mirando en el HTML devuelto como si fuera lo que es, simplemente una cadena de texto.&lt;/p&gt;
&lt;p&gt;Como apunta Albert, hay que tener en cuenta que para usar esto en serio tendr&#237;amos que hacer cache del resultado, apuntarlo en base de datos, lo que sea, pero no estar consultando continuamente a Google porque ser&#237;a muy lento.&lt;/p&gt;
&lt;p&gt;Pero como idea, es divertido y adem&#225;s lo podemos extender a otras &lt;a href="http://www.google.com/help/features.html#currency" target="_blank"&gt;conversiones que nos proporciona Google&lt;/a&gt;&lt;/p&gt;</summary>
    <source>
      <id>http://www.jaimeiniesta.com/?p=174</id>
      <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/07/conversion-de-moneda-con-google-y-ruby/"/>
      <title>Conversi&#243;n de moneda con Google y Ruby</title>
      <updated>2008-08-19T17:10:27+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Hackfest</title>
    <updated>2008-08-20T13:36:09+00:00</updated>
    <published>2008-08-06T12:49:00+00:00</published>
    <id>planetaki.com:905:post:5599284</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/RidingRails/~3/357381758/hackfest"/>
    <summary type="html">&lt;p&gt;And once again, &lt;a href="http://hackfest.rubyonrails.org" target="_blank"&gt;hackfest&lt;/a&gt; is back. Only this time, it&#8217;s better than ever, thanks to &lt;a href="http://weblog.rubyonrails.org/2008/4/2/rails-is-moving-from-svn-to-git" target="_blank"&gt;Git&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;The idea is quite simple. You get 5000 points for each of your patches that get merged to the &lt;a href="http://github.com/rails/rails/tree/master" target="_blank"&gt;core&lt;/a&gt;. The person with the highest points at the end of the month wins.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://hackfest.rubyonrails.org/2008/8" target="_blank"&gt;August hackfest&lt;/a&gt; is already on and almost 3 more weeks to go, so hack on for the first prize &#8211; a free pass to &lt;a href="http://en.oreilly.com/railseurope2008/public/content/home" target="_blank"&gt;RailsConf Europe&lt;/a&gt; ( special thanks goes to O&#8217;Reilly for the prize )&lt;/p&gt;


	&lt;p&gt;If you&#8217;ve never contributed to Rails before, now is a good time. &lt;a href="http://railscasts.com/episodes/113" target="_blank"&gt;This railscast&lt;/a&gt; is a nice head start.&lt;/p&gt;


	&lt;p&gt;Thanks to all those who have contributed to Rails, making it better and better.&lt;/p&gt;</summary>
    <source>
      <id>tag:weblog.rubyonrails.com,2008-08-06:21227</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/RidingRails/~3/357381758/hackfest"/>
      <title>Hackfest</title>
      <updated>2008-08-20T13:36:09+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Using Rails Generators</title>
    <updated>2008-08-05T20:25:14+00:00</updated>
    <published>2008-08-05T19:43:00+00:00</published>
    <id>planetaki.com:905:post:5562036</id>
    <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/356674067/using-rails-generators"/>
    <summary type="html">&lt;p&gt;Most people who start learning Rails today quickly learn about generators.  They&#8217;re easy to use and very handy.&lt;/p&gt;


	&lt;p&gt;Still, like any other code-generation device, it&#8217;s important to understand what they&#8217;re doing when you use them.  I thought that would go without saying, but I should know better.  I remember back in the day of &lt;span class="caps"&gt;ATL COM&lt;/span&gt; programming on Windows, adoption of &lt;span class="caps"&gt;ATL&lt;/span&gt; really took off when Visual Studio added a few wizards to help you create &lt;span class="caps"&gt;COM&lt;/span&gt; components easily.  The number of people who didn&#8217;t realize what it was doing was surprising.  When the smallest bug or issue would come up, they were at a loss to know what their program was doing.  To be fair, I also didn&#8217;t know what the wizards were doing when I started learning, either.  I finally learned how to create &lt;span class="caps"&gt;COM&lt;/span&gt; components by hand (IDL&#8230;.yuck), and once I did a couple, I knew everything I needed to know.  Using the wizards after that was fun and helpful, since I knew how to change (or fix) anything I needed to after the wizard had generated its code.&lt;/p&gt;


	&lt;p&gt;Ok, back to the present&#8230; once in a while I notice that people don&#8217;t really understand Rails generators.  I don&#8217;t really think it&#8217;s worth a blog post to explain all of them, but I did want to mention a quick tip that you might not already be aware of if you&#8217;ve just recently started with Rails: if you do this,&lt;/p&gt;


&lt;pre&gt;c:\myapp&amp;gt; ruby script\generate&lt;/pre&gt;

	&lt;p&gt;(and then wait a minute) you&#8217;ll get a page showing all the options and generators available.&lt;/p&gt;


	&lt;p&gt;You can get specific help on a generator (say, the scaffold generator) like this:&lt;/p&gt;


&lt;pre&gt;c:\myapp&amp;gt; ruby script\generate scaffold&lt;/pre&gt;

	&lt;p&gt;The help that&#8217;s emitted to the console is dense but usually quite complete.&lt;/p&gt;


	&lt;p&gt;Just do me one favor: after using a generator, &lt;strong&gt;learn what it did for you&lt;/strong&gt;.  There&#8217;s nothing a generator can do that you can&#8217;t do yourself.  They just take the tedium out of some common Rails tasks that you&#8217;d otherwise have to do by hand.&lt;/p&gt;


	&lt;p&gt;Now, if you&#8217;d like to see an article on a specific generator, or have other questions about Rails generators, just drop us a comment here.&lt;/p&gt;


&lt;hr /&gt;
&lt;i&gt;New to &lt;span class="caps"&gt;REST&lt;/span&gt; in Rails?  Come to &lt;a href="http://www.purpleworkshops.com/workshops/rest-and-web-services" target="_blank"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt; with Rails&lt;/a&gt; Oct 4, 2008, in Austin, TX&lt;/i&gt;
          
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/SoftiesOnRails?a=YoZspd" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~a/SoftiesOnRails?i=YoZspd" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=xNQ0Dk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=xNQ0Dk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=AcGx7k" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=AcGx7k" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=LoovmK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=LoovmK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/SoftiesOnRails?a=mR00JK" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/SoftiesOnRails?i=mR00JK" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SoftiesOnRails/~4/356674067" height="1" onload="resizeImage( this )" width="1" /&gt;</summary>
    <source>
      <id>tag:www.softiesonrails.com,2008-08-05:25847</id>
      <link rel="alternate" href="http://feeds.feedburner.com/~r/SoftiesOnRails/~3/356674067/using-rails-generators"/>
      <title>Using Rails Generators</title>
      <updated>2008-08-05T20:25:14+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Analiza los cuellos de botella de MySQL con Query-Reviewer</title>
    <updated>2008-08-05T18:42:54+00:00</updated>
    <published>2008-08-05T17:52:56+00:00</published>
    <id>planetaki.com:905:post:5556840</id>
    <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/05/analiza-los-cuellos-de-botella-de-mysql-con-query-reviewer/"/>
    <summary type="html">&lt;p&gt;A ra&#237;z del art&#237;culo &amp;#8220;&lt;a href="http://blog.scoutapp.com/articles/2008/07/29/4-simple-steps-to-detect-and-fix-slow-rails-requests" target="_blank"&gt;4 simple steps to detect &amp;amp; fix slow rails requests&lt;/a&gt;&amp;#8221; he descubierto un plugin muy interesante para detectar cuellos de botella en las consultas a MySQL desde nuestras aplicaciones Rails.&lt;/p&gt;
&lt;p&gt;Se trata de &lt;a href="http://code.google.com/p/query-reviewer/" target="_blank"&gt;query-reviewer&lt;/a&gt;, que se encarga de mostrarnos avisos directamente con una capa flotante en el navegador, cuando estamos en modo de desarrollo. El plugin analiza las consultas realizadas y nos indica si todo va bien, o muestra los avisos de que hay cosas que se podr&#237;an mejorar, por qu&#233; y c&#243;mo.&lt;/p&gt;
&lt;p&gt;Tras un rato examinando los avisos generados y siguiendo sus consejos para a&#241;adir &#237;ndices a las tablas y contadores a algunas asociaciones en los modelos, he incrementado por 3 la velocidad de respuesta de algunas de las partes de mis aplicaciones.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.jaimeiniesta.com/wp-content/uploads/2008/08/picture_4.png" target="_blank"&gt;&lt;img class="alignnone size-full wp-image-171" title="query-reviewer en acci&#243;n" src="http://www.jaimeiniesta.com/wp-content/uploads/2008/08/picture_4.png" height="343" onload="resizeImage( this )" alt="" width="500" /&gt;&lt;/a&gt;&lt;/p&gt;</summary>
    <source>
      <id>http://www.jaimeiniesta.com/?p=170</id>
      <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/05/analiza-los-cuellos-de-botella-de-mysql-con-query-reviewer/"/>
      <title>Analiza los cuellos de botella de MySQL con Query-Reviewer</title>
      <updated>2008-08-05T18:42:54+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Conferencia Rails 2008&amp;#8230; here we go again!</title>
    <updated>2008-08-05T07:12:04+00:00</updated>
    <published>2008-08-05T07:01:50+00:00</published>
    <id>planetaki.com:905:post:5523153</id>
    <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/04/conferencia-rails-2008-here-we-go-again/"/>
    <summary type="html">&lt;p&gt;Aunque este a&#241;o hemos tardado un poco en arrancar, el equipo de organizaci&#243;n de la Conferencia Rails estamos de nuevo a la carga organizando el evento.&lt;/p&gt;
&lt;p&gt;Ya nos puedes enviar tus propuestas de charlas, tanto si son ponencias t&#233;cnicas como casos de &#233;xito (qu&#233; mejor ocasi&#243;n para promocionar tu nueva app)&amp;#8230;&lt;/p&gt;
&lt;p&gt;Toda la informaci&#243;n actualizada en el blog oficial, &lt;a href="http://www.conferenciarails.org" target="_blank"&gt;www.conferenciarails.org&lt;/a&gt; y en nuestro canal de twitter, &lt;a href="http://twitter.com/conferenciaror" target="_blank"&gt;twitter.com/conferenciaror&lt;/a&gt;&lt;/p&gt;</summary>
    <source>
      <id>http://www.jaimeiniesta.com/?p=167</id>
      <link rel="alternate" href="http://www.jaimeiniesta.com/2008/08/04/conferencia-rails-2008-here-we-go-again/"/>
      <title>Conferencia Rails 2008&amp;#8230; here we go again!</title>
      <updated>2008-08-05T07:12:04+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Online Capistrano Tutorial #2</title>
    <updated>2008-08-04T17:06:32+00:00</updated>
    <published>2008-08-04T16:14:00+00:00</published>
    <id>planetaki.com:905:post:5494046</id>
    <link rel="alternate" href="http://weblog.jamisbuck.org/2008/8/4/online-capistrano-tutorial-2"/>
    <summary type="html">&lt;p&gt;The first online Capistrano tutorial session was very successful, thanks to everyone who participated. Now, it&#8217;s time to try again!&lt;/p&gt;


	&lt;p&gt;The second online Capistrano tutorial session is now open for registration: &lt;a href="http://events.capify.org/events/2" target="_blank"&gt;http://events.capify.org/events/2&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;It is scheduled for Wednesday, August 13th, at 7pm (Mountain time), and will last two hours (plus up to an hour at the end for Q&amp;A;). As before, this tutorial is targeted at &lt;em&gt;beginning&lt;/em&gt; Capistrano users, those will little or no prior experience. (If you&#8217;re looking for a session for more advanced users, keep watching this space&#8212;I&#8217;ll probably do one of those eventually, as soon as I can write a curriculum for it.)&lt;/p&gt;</summary>
    <source>
      <id>tag:weblog.jamisbuck.org,2008-08-04:4660</id>
      <link rel="alternate" href="http://weblog.jamisbuck.org/2008/8/4/online-capistrano-tutorial-2"/>
      <title>Online Capistrano Tutorial #2</title>
      <updated>2008-08-04T17:06:32+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Episode 121: Non Active Record Model</title>
    <updated>2008-08-04T11:58:23+00:00</updated>
    <published>2008-08-04T07:00:00+00:00</published>
    <id>planetaki.com:905:post:5477725</id>
    <link rel="alternate" href="http://railscasts.com/episodes/121-non-active-record-model"/>
    <summary type="html">This episode will show you how to make a model which isn't based on Active Record. You may want to do this if a resource isn't backed by the database.</summary>
    <source>
      <id>non-active-record-model</id>
      <link rel="alternate" href="http://railscasts.com/episodes/121-non-active-record-model"/>
      <title>Episode 121: Non Active Record Model</title>
      <updated>2008-08-04T11:58:23+00:00</updated>
    </source>
  </entry>
  <entry>
    <title>Dr Nic for hire</title>
    <updated>2008-08-04T06:06:32+00:00</updated>
    <published>2008-08-04T05:41:42+00:00</published>
    <id>planetaki.com:905:post:5464229</id>
    <link rel="alternate" href="http://drnicwilliams.com/2008/08/04/dr-nic-for-hire/"/>
    <summary type="html">&lt;p&gt;For the last few months I&amp;#8217;ve been contracting to three different projects, and then recently two of them finished, with the &lt;a href="http://imindi.com" target="_blank"&gt;third&lt;/a&gt; being an on-going project for the last two years which will be launched at DEMO in a months&amp;#8217; time. &lt;/p&gt;
&lt;p&gt;So I&amp;#8217;m excited to start looking for a new consulting project to work on. &lt;/p&gt;
&lt;p&gt;Travel or relocation is an option. Full-time salary is probably not an option. Either full-time or several days-per-week is an option. Making me wear a uniform and serve hamburgers through a small window is not an option. Working in an office is an option. Working on an oil rig in the Indian Ocean is not an option. &lt;/p&gt;
&lt;p&gt;My professional background is in telecom billing systems and third-party integrations, including a roving two year stint in various countries between 2005 and 2007 (India, Sweden, Netherlands and Germany). One part of me is excited by the idea of moving overseas again. The other part of me includes two small children and a ten-hour plane flight to get anywhere.&lt;/p&gt;
&lt;p&gt;I do have a PhD from the University of Queensland, though the only proof of it I can find on the InterTubes is on my supervisor&amp;#8217;s 1990&amp;#8217;s-themed &lt;a href="http://www.itee.uq.edu.au/~jaga/" target="_blank"&gt;website&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;In recent years I&amp;#8217;ve worked on several Rails projects, including developing and coaching the founders of  &lt;a href="http://imindi.com" target="_blank"&gt;imindi.com&lt;/a&gt;, a next-generation service for individual and collaborative thinking. I&amp;#8217;ve run a bunch of Introduction to Rails workshops. I&amp;#8217;m with a small group of Australians who recently started soliciting to develop iPhone SDK + Rails applications (under the brand &lt;a href="http://mocra.com" target="_blank"&gt;Mocra&lt;/a&gt;; also, see Garath Townsend&amp;#8217;s free app &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284947240&amp;mt=8" target="_blank"&gt;I Am Here&lt;/a&gt; which is in the top 50 free apps at the moment).&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve written dozens and dozens of blog articles (see an &lt;a href="http://drnicwilliams.com/2007/10/28/showing-off-data-on-a-timeline/" target="_blank"&gt;amusing graph&lt;/a&gt;); authored or hijacked or nudged along dozens and dozens of Ruby projects, JavaScript thingies, and TextMate bundles (see my &lt;a href="http://github.com/drnic" target="_blank"&gt;github profile&lt;/a&gt;). I&amp;#8217;ve even been allowed to talk at various conferences (my favourite talk was the RubiGen session at RubyConf 2007 [&lt;a href="http://rubyconf2007.confreaks.com/d3t1p1_rubigen.html" target="_blank"&gt;video&lt;/a&gt;]), including the exciting &lt;a href="http://www.locaweb.com.br/railssummit/" target="_blank"&gt;Rails Summit Latin American&lt;/a&gt; in Brazil later this year.&lt;/p&gt;
&lt;p&gt;Open Source is for free and Consulting is for money. In both cases I like to work hard, write lots of code, and accumulate and share knowledge.&lt;/p&gt;
&lt;p&gt;It would be wonderful if you can share this post with anyone who would benefit from having me on their team. &lt;/p&gt;
&lt;p&gt;I can be contacted at &lt;a href="mailto:drnicwilliams@gmail.com" target="_blank"&gt;drnicwilliams@gmail.com&lt;/a&gt; or on +61 412 002 126 in GMT+10 time zone.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/DrNic?a=bBUcRk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/DrNic?i=bBUcRk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/DrNic?a=VE080k" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/DrNic?i=VE080k" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/DrNic?a=pS9rCk" target="_blank"&gt;&lt;img src="http://feeds.feedburner.com/~f/DrNic?i=pS9rCk" border="0" onload="resizeImage( this )" /&gt;&lt;/a&gt;
&lt;/div&gt;</summary>
    <source>
      <id>http://drnicwilliams.com/?p=288</id>
      <link rel="alternate" href="http://drnicwilliams.com/2008/08/04/dr-nic-for-hire/"/>
      <title>Dr Nic for hire</title>
      <updated>2008-08-04T06:06:32+00:00</updated>
    </source>
  </entry>
</feed>
