<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Space Vatican - Home</title>
  <id>tag:www.spacevatican.org,2008:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://www.spacevatican.org/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.spacevatican.org/" rel="alternate" type="text/html"/>
  <updated>2008-08-19T22:53:53Z</updated>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-08-19:57</id>
    <published>2008-08-19T22:52:00Z</published>
    <updated>2008-08-19T22:53:53Z</updated>
    <category term="Rails"/>
    <category term="activesupport"/>
    <link href="http://www.spacevatican.org/2008/8/19/fun-with-class-variables" rel="alternate" type="text/html"/>
    <title>Fun with class variables</title>
<content type="html">
            &lt;p&gt;Class variables are a slightly fiddly bit of ruby. They don't always quite behave the way you expect. ActiveSupport bundles up a large number of helpers to deal with the various cases. They're used extensively throughout the framework where the ability to control how things set at the framework level ripple down to subclasses (ie your models and controllers) is important to get right, but they can be pretty handy in your own apps too.&lt;/p&gt;

&lt;h1&gt;The Basics&lt;/h1&gt;

&lt;p&gt;If you're at all familiar with ruby you'll have heard @@. @@ is a bit odd because it creates variables that are visible both from the instance and the class. The value is also shared with subclasses. ActiveSupport adds cattr_accessor which  creates the obvious accessor methods and initializes the value to nil. The accessors are created on both the class and instances of it (the instance writer is optional).&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Foo&lt;/span&gt;
  &lt;span class=&quot;SupportFunction&quot;&gt;cattr_accessor&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;bar&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Support&quot;&gt;Foo&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; nil&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Foo&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;123&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Foo&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;new&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; '123'&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Foo&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;new&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;abc&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Foo&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; 'abc'&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;If we create a subclass, the value is shared:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Derived&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; Foo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Foo&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;123&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; '123'&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;abc&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Foo&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; 'abc'&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Other slightly odd things can happen:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;self.bar&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@@&lt;/span&gt;bar&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;self.bar=&lt;/span&gt;value
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@@&lt;/span&gt;bar&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Derived&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; Base&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;SupportFunction&quot;&gt;cattr_accessor&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;bar&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Derived2&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; Base&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;SupportFunction&quot;&gt;cattr_accessor&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;bar&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;123&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived2&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;abc&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; '123'&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;So now the subclasses have independent class variables named @@bar. However if you set Base.bar before the Derived and Derived2 classes are created &lt;a href=&quot;#note_1&quot;&gt;[1]&lt;/a&gt; then everyone will be share the base class' value as before. To summarize it's rather fiddly and often unintuitive. It also does not allow the fairly common pattern of having the base class setting a default value that subclasses can override. If you don't know about this then it can lead to odd situations. You'll have code that works fine in dev mode, but not in production (since in development classes are trashed and recreated between requests which obviously interacts with all this) or tests that pass when run individually but fail when you run several of them at the same time.&lt;/p&gt;

&lt;h1&gt;Classes are objects&lt;/h1&gt;

&lt;p&gt;Classes are no exception in ruby, like most things (everything?) they are objects, and like objects they can have instance variables. These instance variables are just normal instance variables: they don't have the odd scoping rules that @@ variables have. Base classes and derived classes have completely independent values.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;bar&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;123&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt;
      &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;bar&lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;bar=&lt;/span&gt; value
      &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;bar&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; value
    &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Derived&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; Base&lt;/span&gt;&lt;/span&gt;; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; '123&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; nil&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;abc&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; &amp;quot;123&amp;quot;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Less prone to unwanted surprises, but not without shortfalls as you cannot make a default from a base class propagate down (without resorting to tricks with self.inherited).&lt;/p&gt;

&lt;h1&gt;Inheritable Tricks&lt;/h1&gt;

&lt;p&gt;ActiveSupport adds class_inheritable_accessor. This provides something closer in behaviour to what you might expect: base classes can provide defaults and subclasses inherit those defaults and can overwrite them without affecting other subclasses or the base class.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;
  class_inheritable_accessor &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;value&lt;/span&gt;
  &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;123&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Derived&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; Base&lt;/span&gt;&lt;/span&gt;; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Derived2&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; Base&lt;/span&gt;&lt;/span&gt;; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; '123'&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;abc&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; '123'&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived2&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; '123&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;So far so good. We override the value on derive and didn't perturb anyone else. Unfortunately there are some drawbacks:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;xyz&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Support&quot;&gt;Derived2&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; '123&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Oh dear. Even though Derived2 never overrode any values the change we made to Base didn't propagate. In other words the default values are baked into the subclass at the time that it is created. This is down to the way that class_inheritable_accessor is implemented: The classes have an instance variable @inheritable_attributes (like we saw above) that is a hash with all the attributes. The accessor methods just pull the values in and out of the hash. When a class is subclassed the subclass gets a copy of @inheritable_attributes. Once this has happened, nothing links the base class' attributes with the subclass.&lt;/p&gt;

&lt;h1&gt;Bags of tricks&lt;/h1&gt;

&lt;p&gt;ActiveSupport also provides class_inheritable_array and class_inheritable_hash. They both use class_inheritable_accessor as their underlying mechanism. When you set a class_inheritable_array or a  class_inheritable_hash you are actually concatenating (or merging) with the value inherited from the super class.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;
  class_inheritable_hash &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;attrs&lt;/span&gt;
  &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;attrs&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;name&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Fred&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;}
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Derived&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; Base&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;attrs&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;export&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Pain&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;}
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;attrs&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; {:name =&amp;gt; 'Fred', :export =&amp;gt; 'Pain'}&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;These aren't particularly magic but are a handy shortcut.&lt;/p&gt;

&lt;h1&gt;Delegation for the nation&lt;/h1&gt;

&lt;p&gt;ActiveSupport's final trick is superclass_delegating_accessor, added in rails 2.0.1. At first it appears very similar to class_inheritable_accessor:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;
  superclass_delegating_accessor &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;properties&lt;/span&gt;
  &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;properties&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; []
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Derived&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; Base&lt;/span&gt;&lt;/span&gt;; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;This time however we can do this:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;properties&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;useless&lt;/span&gt;]
  &lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;properties&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; [:useless]&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;superclass_delegating_accessor creates regular instance variables in the class. The interesting bit is the reader method: it looks at the current class and checks if the appropriate instance variable is defined. If so, it returns it, if not it calls super (ie gets the superclass' instance variable) and so it. It stops when it reaches the class that created the superclass_delegating_accessor.&lt;/p&gt;

&lt;p&gt;Unfortunately it doesn't always behave as you would expect: in place modifications will propagate upwards.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Derived&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;properties&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;derived&lt;/span&gt;]
  &lt;span class=&quot;Support&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;properties&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;=&amp;gt; [:useless, :derived]&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Which is just horrible. The example is slightly less contrived when dealing with objects which you tend to modify in place. ActiveResource ran into this with its site property (an instance of URI) and rolls its own thing specially for this property that freezes things so that subclasses don't mess with their parents.&lt;/p&gt;

&lt;p&gt;Unfortunately it's a decidedly quirky corner of ruby. Several different options with subtly different semantics that when they go wrong, go wrong in subtle ways that are easy to overlook and with no clear winner. Be careful!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#1_source&quot;&gt;[1]&lt;/a&gt; The important bit is actually when Derived and Derived2 create their @@bar variable. cattr_accessor does this for you so in this case the variable is created at the same time the class is.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-08-17:54</id>
    <published>2008-08-17T04:44:00Z</published>
    <updated>2008-08-17T04:46:55Z</updated>
    <category term="Rails"/>
    <link href="http://www.spacevatican.org/2008/8/17/counting-on-both-hands" rel="alternate" type="text/html"/>
    <title>Counting on both hands</title>
<content type="html">
            &lt;p&gt;This is more of an SQL hint than anything else, but it's something I've found useful a number of times. If SQL scares you, now's the time to turn back (or crack open a beer - dutch courage).&lt;/p&gt;

&lt;p&gt;More often than not if I'm not displaying or editing something then I'm counting. How many unpaid invoices are there, how many customers to I have who were active in the last 6 months etc...&lt;/p&gt;

&lt;p&gt;I'm sure I'm not teaching anyone anything if I say that Rails has some helpers for this, for example&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Support&quot;&gt;Invoice&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;conditions&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;status&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;unpaid&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;}
&lt;span class=&quot;Support&quot;&gt;Customer&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;conditions&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;updated_at &amp;gt; ?&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;6&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;months&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;ago&lt;/span&gt;]
&lt;span class=&quot;Support&quot;&gt;Invoice&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;total&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;conditions&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;status&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;unpaid&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;}
&lt;/pre&gt;

&lt;p&gt;From top to bottom this counts the number of unpaid invoices, the number of customers updated in the last 6 months and the total value of all unpaid invoices. Pretty much any option you can stick in a find you can also use with the calculation helpers, for example:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Customer&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;weight&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;joins&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;orders&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;products&lt;/span&gt;}
  &lt;span class=&quot;Support&quot;&gt;Customer&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;weight&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;joins&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;orders&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;products&lt;/span&gt;}, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;group&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;customers.id&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;This sums the weight of all the items ordered by our customers (ignoring for now the quantity of a product in a given order). The second example groups this by customer.&lt;/p&gt;

&lt;p&gt;But what if you want to sum (or count) more than one thing? For example I might want to know the number and the total value of the unpaid invoices. You could of course just do one and then the other but that feels a little wasteful: we're asking the database to scan over the corresponding invoices once and then we turn around and ask it do it again. Luckily with some raw sql it's not hard to do this in one go:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  connection.&lt;span class=&quot;Entity&quot;&gt;select_all&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;SELECT count(*), SUM(total) from invoices where status='unpaid'&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;But what if you wanted to count more than one thing? For example I might want a count of all outstanding invoices and a count of those with non trivial value (say more than $10). Again easy enough to write as two queries, but it would be nice to get it all back in one go.&lt;/p&gt;

&lt;p&gt;The key to this is understanding the link between summation and counting. To use a technical term, we're interested in indicator functions. If we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a set X (which in our terms corresponds to all the rows in a table (or to be more correct, all the rows your query would return if it had no WHERE clause)&lt;/li&gt;
&lt;li&gt;a subset A (the rows our WHERE clause would select). &lt;/li&gt;
&lt;li&gt;a function I such that I(x) is 1 if x is in A and 0 if not&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the cardinality (the number of things in it)  of A is the sum of I(x) for x ranging over X. &lt;/p&gt;

&lt;p&gt;That sounds complicated, but if you think about it, all it is saying is that to count the rows in a table you could use&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;SELECT&lt;/span&gt; SUM(&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;Keyword&quot;&gt;from&lt;/span&gt; foos
&lt;/pre&gt;

&lt;p&gt;Here our indicator function is dead simple: it always returns 1.&lt;/p&gt;

&lt;p&gt;These three queries return the same thing&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Keyword&quot;&gt;SELECT&lt;/span&gt; COUNT(*) &lt;span class=&quot;Keyword&quot;&gt;from&lt;/span&gt; invoices &lt;span class=&quot;Keyword&quot;&gt;where&lt;/span&gt; status=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;pending'&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;SELECT&lt;/span&gt; SUM(&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;Keyword&quot;&gt;from&lt;/span&gt; invoices &lt;span class=&quot;Keyword&quot;&gt;where&lt;/span&gt; status=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;pending'&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;SELECT&lt;/span&gt; SUM( IF(status=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;pending'&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;Keyword&quot;&gt;from&lt;/span&gt; invoices
&lt;/pre&gt;

&lt;p&gt;The third form is the one we're interested in. Again it shouldn't be hard to spot why it works: for each row that matches we count 1, for all others we count 0. When we add these all up we're just going to get the number of times we counted 1, i.e. the number of matching rows. We wouldn't want to use that on its own (it won't use an index and COUNT(*) probably takes some shortcuts) but in the context of our problem it's just what we need:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Keyword&quot;&gt;SELECT&lt;/span&gt; COUNT(*) as count, SUM(IF(total&amp;lt;&lt;span class=&quot;Constant&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;)) as small_invoices &lt;span class=&quot;Keyword&quot;&gt;where&lt;/span&gt; status = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;pending'&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;will return the number of unpaid invoices and the number of invoices whose total is less than 10 dollars. Here our IF functions are our indicator functions: they return 1 if the condition evaluates to true and 0 if not.&lt;/p&gt;

&lt;h1&gt;Is it actually useful?&lt;/h1&gt;

&lt;p&gt;It's going to depend on your data and queries. The ones shown here are probably too simple for it to be of any use since they also had to be easy to explain. When you push some of your conditions from the WHERE clause into the IF statements you are effectively stopping the database from using any indexes to solve those conditions. This can hurt you, but obviously if you weren't using (or don't have) indexes that the database could have used for those conditions then you haven't lost anything.&lt;/p&gt;

&lt;p&gt;The other basic premise is that if the database going over some set of data it might as well be counting more than one thing. So if in order to find rows satisfying condition A the database needs to scan some subset X and in order to satisfy condition B the database also needs to scan that same subset X then you're onto a winner. If on the other hand the two are completely distinct (or if X is hopelessly big) then you won't be saving much.&lt;/p&gt;

&lt;p&gt;Typically I've used this the most in reporting style applications where having applied a common set of conditions I want to count the number of occurrences of a large number of features. Not something to be using willy-nilly, but a neat trick to have in your toolbox. Use it wisely. And as with all performance things, don't do things blindly just because you read somewhere that it's faster. Profile, measure and so on before and after and come to your own conclusions.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-08-09:41</id>
    <published>2008-08-09T18:30:00Z</published>
    <updated>2008-08-09T18:31:16Z</updated>
    <category term="Rails"/>
    <link href="http://www.spacevatican.org/2008/8/9/when-ducks-go-mutant" rel="alternate" type="text/html"/>
    <title>When ducks go mutant</title>
<content type="html">
            &lt;p&gt;Ruby is a permissive language. In general we don't care what objects are, as long as they respond in certain ways to certain methods: &quot;If it walks like a duck and quacks like a duck, I would call it a duck&quot;.&lt;/p&gt;

&lt;p&gt;As you may recall, in Rails 2.1 there was a rewrite of the :include mechanism, however the old mechanism persists for compatiblity reasons. When using the new mechanism, the :included associations are not joined, and so if any part of your query looks references the tables that would formerly have been joined it won't work.&lt;/p&gt;

&lt;p&gt;To work around this Rails looks at the conditions, order, select statements and so on to see if any of them mention tables other than the main table. If they do then the fallback to the old code is triggered and everything works fine. The code that detects tables in the order clause looks something like&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
   &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt; [] &lt;span class=&quot;Keyword&quot;&gt;unless&lt;/span&gt; order &lt;span class=&quot;Keyword&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; order.&lt;span class=&quot;Entity&quot;&gt;is_a?&lt;/span&gt;(&lt;span class=&quot;Variable&quot;&gt;String&lt;/span&gt;)
   order.&lt;span class=&quot;Entity&quot;&gt;scan&lt;/span&gt;(&lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;StringRegexpSpecial&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;StringRegexpSpecial&quot;&gt;\w&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;]&lt;/span&gt;&lt;/span&gt;+&lt;span class=&quot;StringRegexp&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.?&lt;span class=&quot;StringRegexpSpecial&quot;&gt;\.&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;/&lt;/span&gt;&lt;/span&gt;).&lt;span class=&quot;Entity&quot;&gt;flatten&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;The code is quite simple: if we ever have &quot;something.&quot; then that means we're using the something table.&lt;/p&gt;

&lt;p&gt;The code that eventually adds the order to the statement looks something like&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  sql &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt; ORDER BY &lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;order&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;The code for the other options is similar.&lt;/p&gt;

&lt;p&gt;So what's the problem here? If as the api docs indicate, you pass a string containing a fragment of sql then nothing at all is wrong. However some people (I assume that the :conditions option is the origin of this habit) have taken to doing things like&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Foo&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;order&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;bars&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;]
&lt;/pre&gt;

&lt;p&gt;Before 2.1, this happens to work, because the default to_s on an array just joins the strings together. However the table scanning code won't scan an array (My guess is that the explicit check for string was because people quite legitimately write :order =&gt; :name and things like that). So if you've got a select or order clause specified as an array that depends on an included able it will break when you move to rails 2.1.&lt;/p&gt;

&lt;p&gt;It's a complete accident that this ever worked (and it breaks if you were to try anything like :order =&gt;['name desc', 'age desc']), but that isn't a huge amount of comfort when code that has been working suddenly stops working. You could probably waste a lot of time before working out that it was specifying the order option as an array, which obviously is not a good thing (and makes people scared of upgrading). On the other hand it's hard to anticipate how people will use things and explicitly checking types and so on isn't a very rubyish thing to do and could get in the way of legitimate uses.&lt;/p&gt;

&lt;p&gt;I'm not sure how a framework provider should handle this in the general case. It's a delicate balance between not stifling some of flexibility ruby offers and helping programmers not rely on things that only work by accident.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-08-08:40</id>
    <published>2008-08-08T18:36:00Z</published>
    <updated>2008-08-10T10:03:21Z</updated>
    <category term="Rails"/>
    <category term="activerecord"/>
    <link href="http://www.spacevatican.org/2008/8/8/nested-includes-and-joins" rel="alternate" type="text/html"/>
    <title>Nested includes and joins</title>
<content type="html">
            &lt;p&gt;Nested eager loads are a not entirely obvious bit of rails syntax. It's not hard once you get it though. In a nutshell you have to tell ActiveRecord how it should walk through the associations (i.e. just listing them isn't enough). Before we get going it's worth pointing out that although I've written :include everywhere, everything I've said applies equally to :include and :joins (see my previous post on the &lt;a href=&quot;http://www.spacevatican.org/2008/6/22/the-difference-between-include-and-joins&quot;&gt;difference&lt;/a&gt; between the two).&lt;/p&gt;

&lt;p&gt;When you are nesting includes, you're building up a data structure that is inherently recursive. There are 3 rules for nested :includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always use the association name. Not the table name, not the class name but the association name (whatever it is that you typed just after belongs_to, has_many etc...). A correlation is that if you don't have all your associations set up, you're dead in the water. If you've got one side of a relationship Rails won't infer the other for you.&lt;/li&gt;
&lt;li&gt;If you want to load multiple associations from a model, use an array.&lt;/li&gt;
&lt;li&gt;If you want to load an association and some of its child associations then use a hash. The key should be the parent association name, the value should be a description of the child associations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now just combine those 3 rules and apply recursively. As an aid here's a quick snippet that takes an include option (such as [:comments, {:posts =&gt; :authors}]) and describes which associations are loaded. The structure is the same as the code in activerecord that handles the :include option, so it should give some insight into how things work.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;describe&lt;/span&gt; associations, from &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;base&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;case&lt;/span&gt; associations
  &lt;span class=&quot;Keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;Symbol&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;then&lt;/span&gt; puts &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;load &lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;associations&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; from &lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;from&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;then&lt;/span&gt; associations.&lt;span class=&quot;Entity&quot;&gt;each&lt;/span&gt; {|&lt;span class=&quot;Variable&quot;&gt;a&lt;/span&gt;| describe a, from}
  &lt;span class=&quot;Keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;Hash&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;then&lt;/span&gt;
    associations.&lt;span class=&quot;Entity&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;parent&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;child&lt;/span&gt;|
      &lt;span class=&quot;Keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Invalid hash - key must be an association name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;unless&lt;/span&gt; parent.&lt;span class=&quot;Entity&quot;&gt;is_a?&lt;/span&gt;(&lt;span class=&quot;Variable&quot;&gt;Symbol&lt;/span&gt;)
      describe parent, from
      describe child, parent
    &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;This code isn't too hard to understand. It's all about the class of the associations parameter&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The easy case is if it's a string or a symbol: what we've got is just the name of an association, so just go ahead and load it.&lt;/li&gt;
&lt;li&gt;If what we've got is an array, then just call ourselves recursively on the contents of that array.&lt;/li&gt;
&lt;li&gt;if what we've got is a hash, then for each key value pair:
&lt;ul&gt;
&lt;li&gt;Load the association specified by the key (the parent association)&lt;/li&gt;
&lt;li&gt;Load the associations specified by the value (from the from the parent association).&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It produces (ugly) output like this:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  describe [{&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt;}, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;category&lt;/span&gt;]
load comments from base
load user from comments
load category from base
&lt;/pre&gt;

&lt;p&gt;which is exactly what activerecord would do. If you see something like &quot;load user from comments&quot; but instances of Comment don't have an association named user then you've screwed up.&lt;/p&gt;

&lt;h2&gt;Examples&lt;/h2&gt;

&lt;p&gt;Still confused ? Here are some examples, from simple to complicated (these are purely examples of the :include syntax - don't see this as a recommendation to actually load 10 layers of nested associations). The models are from a hypothetical book selling application and are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Book&lt;/li&gt;
&lt;li&gt;Author&lt;/li&gt;
&lt;li&gt;Comment&lt;/li&gt;
&lt;li&gt;User&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Books belong to authors, and users of the site can leave a comment on any book. The obvious associations are defined. In addition user has a favourite_books association and through the friends association they can list other users who taste in books they generally share.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;author&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;I hope I don't have to explain that one to anyone :-)&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;author&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt;]
&lt;/pre&gt;

&lt;p&gt;We want to include both the author and comments, so we place the two names in an array&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;author&lt;/span&gt;, {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt;}]
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; [{&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt;}]
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt;}
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt;]}
&lt;/pre&gt;

&lt;p&gt;In the first example we still want to include author and comments, but now we want to include an association from comments. From the 3rd rule we need a hash containing the key :comments and with corresponding value a description of the associations from the Comment model that we want to load (ie just :user in this case).&lt;/p&gt;

&lt;p&gt;In the next 3 examples we just want to include the comments and the user from each comment. These three forms are entirely equivalent (which should be fairly obvious).&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;favourite_books&lt;/span&gt;}}
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;favourite_books&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;author&lt;/span&gt;}}}
&lt;/pre&gt;

&lt;p&gt;Here we are loading the books' comments, the user for each comment and the favourite books for each of those users. In the second example we're also loading the author for each of those favourite books. You can keep on nesting these as far as you want.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;favourite_books&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;author&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt;]}}}
&lt;/pre&gt;

&lt;p&gt;Now we've come full circle - on each favourite book we've loaded the comments&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; 
    {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt; =&amp;gt; [
       &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;friends&lt;/span&gt;, 
       {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;favourite_books&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;author&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt;]}
]}}
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; 
    {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt; =&amp;gt; [
      {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;friends&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;favourite_books&lt;/span&gt;}, 
      {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;favourite_books&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;author&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt;]}
]}}
  &lt;span class=&quot;Support&quot;&gt;Book&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt; =&amp;gt; 
    {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user&lt;/span&gt; =&amp;gt; 
      {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;friends&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;favourite_books&lt;/span&gt;,
       &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;favourite_books&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;author&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;comments&lt;/span&gt;]
}}}
&lt;/pre&gt;

&lt;p&gt;Our final examples. In addition to the favourite_books association, we're loading a user's friends, and in the second case the favourite books of those friends. The last two examples are identical: we can either have an array with two 1 item hashes, or just one hash with 2 items. We can't do that in the first example: because we're not loading any associations from friends we can't make it into a hash (what would the corresponding value be?) &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-07-18:35</id>
    <published>2008-07-18T22:02:00Z</published>
    <updated>2008-08-04T21:34:06Z</updated>
    <category term="Rails"/>
    <category term="controllers"/>
    <category term="rails"/>
    <link href="http://www.spacevatican.org/2008/7/18/parametrised-to-the-max" rel="alternate" type="text/html"/>
    <title>Parametrised to the max</title>
<content type="html">
            &lt;p&gt;If you&#8217;ve played with Rails for more that about 3 minutes you&#8217;ll know that the params hash can itself contain hashes. If you use form_for/fields_for then you&#8217;re used to things like params[:user] containing those fields pertaining to the user and things like that. But it can also contain arrays, arrays of hashes and so on. &lt;/p&gt;

&lt;p&gt;Fundamentally html forms don&#8217;t know about any sort of structured data. All they know about is name-value pairs. Rails tacks some conventions onto parameter names which it uses to express some structure.&lt;/p&gt;

&lt;p&gt;A lot of the time you don&#8217;t really care about how this happens. You use the helpers, rails generates its magic form element names and more magic on the other side stuffs that into your params hash. Every now and again you need to head off the beaten track, and there it&#8217;s useful to understand how things all fit together (eg if you are generating data to submit via javascript).&lt;/p&gt;

&lt;h2&gt;Boring cases &amp;amp; parlour tricks&lt;/h2&gt;

&lt;p&gt;First off we&#8217;ll need a way of trying out things. You could of course just mock up a form with the appropriate input elements but this would massively slow down the process of trying out stuff which is never a good thing. Instead we can tap into what Rails uses. Just open up a script/console prompt:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Support&quot;&gt;ActionController&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;AbstractRequest&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;parse_query_parameters&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name=fred&amp;amp;phone=0123456789&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;phone&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;0123456789&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}
&lt;/pre&gt;

&lt;p&gt;Just stick name=value pairs (joined with &amp;amp;) into a string and pass it to the above function. What you get back is what would be in the params hash in your controller. From now on, for the sake of brevity I&#8217;ll just write parse instead of ActionController::AbstractRequest.parse_query_parameters.&lt;/p&gt;

&lt;p&gt;If you&#8217;ve ever looked at the html your app generates you will have seen form inputs with names like user[name] (as generated by the text_field or form_for helpers). This notation indicates that the user parameter should be a hash, and that here we&#8217;re talking about the name key in that hash:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user[name]=fred&amp;amp;user[phone]=0123456789&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;phone&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;0123456789&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}}
&lt;/pre&gt;

&lt;p&gt;The other basic structure is an array. By default, repeated parameters with the same name are ignored and only the first appearance counts.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name=fred&amp;amp;name=bob&amp;amp;name=henry&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}
&lt;/pre&gt;

&lt;p&gt;If the name ends with [] then instead of discarding extra occurrences they are accumulated in an array:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;aliases[]=fred&amp;amp;aliases[]=bob&amp;amp;aliases[]=dark+prince&amp;amp;things[]=foo&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;aliases&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bob&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;dark prince&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;], &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;things&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;foo&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]}
&lt;/pre&gt;

&lt;p&gt;One use case might be a set of checkboxes which indicate which folders a user has to. Just create all your checkboxes with the name accessible_folder_ids[] and with the ids of the folders as values, for example:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;folders&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;f&lt;/span&gt;| &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    &amp;lt;%= check_box_tag 'user[accessible_folder_ids][]', f.id %&lt;span class=&quot;String&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;%=&lt;/span&gt; h f.&lt;span class=&quot;Entity&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%&amp;gt;&lt;/span&gt; &amp;lt;br/&lt;span class=&quot;String&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Stick this in a form and when you submit it, params[:user][:accessible_folder_ids] will be an array containing the ids of the folders the user can play with.&lt;/p&gt;

&lt;h2&gt;Nested parameters for dummies&lt;/h2&gt;

&lt;p&gt;We can nest hashes if we want. For example perhaps a user has an associated model such as an address:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user[name]=fred&amp;amp;user[address][town]=cambridge&amp;amp;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;         user[address][line1]=4+Station+road&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;address&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;line1&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;4 Station road&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;town&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;cambridge&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}}}
&lt;/pre&gt;

&lt;p&gt;A member of a hash can of course be an array. To do this you just append [] to the parameter name, as with a top level array parameter:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user[aliases][]=fred&amp;amp;user[aliases][]=bob&amp;amp;user[aliases][]=dark+prince&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;aliases&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bob&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;dark prince&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]}}
&lt;/pre&gt;

&lt;p&gt;The array can be several levels down: we can improve a previous example of a user with an address by saying that the address should have a lines array containing the lines from the address. Start with user[address][lines] and then just append [] to indicate the parameter should be an array:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user[name]=fred&amp;amp;user[address][town]=cambridge&amp;amp;user[address][lines][]=Random+house&amp;amp;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;         user[address][lines][]=4+Station+road&amp;amp;user[address][lines][]=By+the+station&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt; {
      &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;address&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{ 
        &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;lines&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Random house&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;4 Station road&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;By the station&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;],
        &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;town&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;cambridge&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    }}}
&lt;/pre&gt;

&lt;p&gt;There&#8217;s another case in which nesting like this can be useful. Support for example that we have a list of users and we want the user to be able to change as many of them as they want with one edit operation. If we use the id of the records as the first key then this is easy:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users[1][name]=fred&amp;amp;users[1][email]=fred@example.com&amp;amp;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;         users[2][name]=bob&amp;amp;users[2][email]=bob@example.com&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{
      &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;1&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;email&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred@example.com&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, 
      &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;2&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bob&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;email&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bob@example.com&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
}}}
&lt;/pre&gt;

&lt;p&gt;The corresponding controller code is similarly simple&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  params[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;users&lt;/span&gt;].&lt;span class=&quot;Entity&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;id&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;new_attributes&lt;/span&gt;|
    &lt;span class=&quot;Support&quot;&gt;User&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt;(id).&lt;span class=&quot;Entity&quot;&gt;update_attributes&lt;/span&gt; new_attributes
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;(Handling errors and invalid entries when editing multiple elements is an interesting problem in itself and is left as an exercise to the reader). If you are using the Rails form helpers, the :index option does precisely this:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;SupportFunction&quot;&gt;helper&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;text_field&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;person&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&amp;lt;input id=&amp;quot;person_name&amp;quot; name=&amp;quot;person[name]&amp;quot; size=&amp;quot;30&amp;quot; type=&amp;quot;text&amp;quot; /&amp;gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;SupportFunction&quot;&gt;helper&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;text_field&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;person&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;index&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;
    =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&amp;lt;input id=&amp;quot;person_1_name&amp;quot; name=&amp;quot;person[1][name]&amp;quot; size=&amp;quot;30&amp;quot; type=&amp;quot;text&amp;quot; /&amp;gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;h2&gt;Editing multiple objects&lt;/h2&gt;

&lt;p&gt;An interesting case is a form allowing us to create several models, for example to add several users to a mailing list. To do this we use parameters of the form users[][name]. This says that users is an array and we&#8217;re pushing an hash with key name onto it. So for example&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users[][name]=fred&amp;amp;users[][email]=fred@example.com&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;email&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred@example.com&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}]}
&lt;/pre&gt;

&lt;p&gt;So how does rails know when one record is finished and the next start? Simple: if we&#8217;ve already had a users[][name] parameter and we see a new one then we can usually assume that the next one must belong to a new user&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users[][name]=fred&amp;amp;users[][email]=fred@example.com&amp;amp;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;         users[][name]=bob&amp;amp;users[][email]=bob@example.com&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;email&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred@example.com&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, 
                  {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bob&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;email&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bob@example.com&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}]}
&lt;/pre&gt;

&lt;p&gt;To continue with a previous example, a user might have several addresses:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user[name]=fred&amp;amp;user[addresses][][line]=24+bob+street&amp;amp;user[addresses][][town]=cambridge&amp;amp;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;         user[addresses][][line]=1+market+square&amp;amp;user[addresses][][town]=bedford&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;user&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;addresses&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[
        {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;line&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;24 bob street&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;town&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;cambridge&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}, 
        {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;line&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;1 market square&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;town&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bedford&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}]
}}
&lt;/pre&gt;

&lt;h2&gt;Turtles all the way down&lt;/h2&gt;

&lt;p&gt;Hashes can be nested as much as you want:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users[a][b][c][d]=fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    =&amp;gt; {&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;a&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;b&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;c&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;d&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}}}}}
&lt;/pre&gt;

&lt;p&gt;Arrays can&#8217;t be nested: you can can&#8217;t for example have a parameter which is an array of arrays. You can have a hash with an array parameter or an array of hashes but in general there can only be one level of &#8216;arrayness&#8217;. It&#8217;s easy enough to see why this is: arrays are built by repeating the same parameter name multiple times, however if you are inside an array then parameter name repetition is precisely what rails uses to determine whether it should move on to the next array element&lt;a href=&quot;#note_1&quot;&gt;[1]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To an extent this can be sidestepped, for example instead of an array of users you can have a hash of users keyed by id. If your data structure is genuinely just an array you can always make it into a hash that is keyed by array index. For example if we had a form displaying a list of users and each user has a name and a list of aliases then the following query string parses into what we want:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  parse &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users[1][name]=fred&amp;amp;users[1][aliases][]=joker&amp;amp;users[1][aliases][]=the+bat&amp;amp;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;         users[2][name]=bob&amp;amp;users[2][aliases][]=bobbo&amp;amp;users[2][aliases][]=bobster&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  =&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;users&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;1&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;fred&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;aliases&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;joker&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;the bat&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]},
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;2&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;{&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bob&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;aliases&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bobbo&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;bobster&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]}
}}
&lt;/pre&gt;

&lt;h2&gt;Where it can go wrong&lt;/h2&gt;

&lt;p&gt;Consider the following query string:&lt;/p&gt;

&lt;pre&gt;
  user[aliases][]=fred&amp;user[aliases][name]=fred
&lt;/pre&gt;

&lt;p&gt;This can&#8217;t work: user[aliases][] indicates that user has an aliases attribute that&#8217;s an array, but user[aliases][name] indicates that user has an aliases attribute that&#8217;s a hash. There are other ways in which this can happen, but the result is the same:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  &lt;span class=&quot;Variable&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;Variable&quot;&gt;Conflicting&lt;/span&gt; types &lt;span class=&quot;Keyword&quot;&gt;for&lt;/span&gt; parameter containers
&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;#1_source&quot;&gt;[1]&lt;/a&gt; This is also the reason for the problem Xavier mentions in his comment. Checkboxes submit no value if they are not checked, however it&#8217;s rather convenient to create the illusion that they send (for example) 1 if the box is checked, 0 if not.&lt;/p&gt;

&lt;p&gt;The rails check_box helper does this by adding a hidden field with the same parameter name. If the checkbox submits nothing then the hidden field &#8220;wins&#8221; and submits 0, if the checkbox is checked then it wins because it&#8217;s the first parameter. However since rails uses parameter name repetition to  distinguish between elements of an array the hidden parameter causes rails to start a new array element. I don&#8217;t know of a good workaround other than using a hash instead of an array or using check_box_tag instead of check_box.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-06-22:32</id>
    <published>2008-06-22T09:12:00Z</published>
    <updated>2008-06-22T09:23:21Z</updated>
    <category term="Rails"/>
    <category term="activerecord"/>
    <link href="http://www.spacevatican.org/2008/6/22/the-difference-between-include-and-joins" rel="alternate" type="text/html"/>
    <title>The difference between :include and :joins</title>
<content type="html">
            &lt;p&gt;I think some people occasionally mix up :include and :joins (or possibly don&#8217;t know of the existance of :joins).&lt;/p&gt;

&lt;p&gt;:include is for loading associations. Before Rails 2.1 it will always left outer join the appropriate tables, starting with rails 2.1 it will either load them with a separate query or it will join the appropriate tables.&lt;/p&gt;

&lt;p&gt;:joins is for joining (duh). It either takes an sql fragment (eg &#8220;INNER JOIN foos on foos.id = foo_id&#8221;) or association names in a variety of ways and joins the relevant tables. For example:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;joins&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;products&lt;/span&gt;
&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;joins&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;products&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;customers&lt;/span&gt;]
&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;joins&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;products&lt;/span&gt;, {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;customers&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;friends&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;foes&lt;/span&gt;]}]
&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;joins&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;products&lt;/span&gt;, {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;customers&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;friends&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;parents&lt;/span&gt;}}]
&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;joins&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;order&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;customer&lt;/span&gt; =&amp;gt; {&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;address&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;some_other_association&lt;/span&gt;}}}
&lt;/pre&gt;

&lt;p&gt;and so on. You can nest these as deeply as you want (although bear in mind that if you end up requiring a 23 way join you may want to rethink your strategy).  The same notation for nested associations is used by :include. The one difference is that :joins creates inner joins for you (if you desperately need those outer joins, you can always use the string form of :joins, but you will  have to write the sql fragment explicitly).&lt;/p&gt;

&lt;p&gt;If what you want is to use attributes from the joined tables for sorting or in your conditions then both :include and :joins will work since they both cause the relevant tables to be joined. But :include then does a lot more work massaging the results that come back from the database, instantiating lots of activerecord objects, gluing together all the relationships in the appropriate manner. If all you wanted was to order or filter results based on some of the joined attributes then this work is wasted.&lt;/p&gt;

&lt;p&gt;Just to show that I&#8217;m not making things up, I performed the following unscientific test:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Support&quot;&gt;Benchmark&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;bm&lt;/span&gt;(&lt;span class=&quot;Constant&quot;&gt;7&lt;/span&gt;) &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;x&lt;/span&gt;|
  x.&lt;span class=&quot;Entity&quot;&gt;report&lt;/span&gt;(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;include:&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;Support&quot;&gt;Customer&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;include&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;customer_detail&lt;/span&gt;, 
                 &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;conditions&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;customer_details.date_of_birth &amp;gt;= '1980-01-1'&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;  
  x.&lt;span class=&quot;Entity&quot;&gt;report&lt;/span&gt;(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;joins:&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;
    &lt;span class=&quot;Support&quot;&gt;Customer&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;joins&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;customer_detail&lt;/span&gt;,
                 &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;conditions&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;customer_details.date_of_birth &amp;gt;= '1980-01-1'&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Some customers have provided extra details which we store in a separate table, and we want to get all customers born after 1980.&lt;/p&gt;

&lt;p&gt;The results:&lt;/p&gt;

&lt;table&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;user&lt;/th&gt;&lt;th&gt;system&lt;/th&gt;&lt;th&gt;total&lt;/th&gt;&lt;th&gt;real&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;include&lt;/td&gt;&lt;td&gt;1.310000&lt;/td&gt;&lt;td&gt;0.040000&lt;/td&gt;&lt;td&gt;1.350000&lt;/td&gt;&lt;td&gt;(  1.532910)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;joins&lt;/td&gt;&lt;td&gt;0.350000&lt;/td&gt;&lt;td&gt;0.040000&lt;/td&gt;&lt;td&gt;0.390000&lt;/td&gt;&lt;td&gt;(  0.454001)&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;In short, don&#8217;t use :include unless you will actually be accessing those associations and want to avoid the hit caused by loading them from the database one by one.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-06-10:17</id>
    <published>2008-06-10T00:31:00Z</published>
    <updated>2008-06-10T00:32:20Z</updated>
    <category term="Rails"/>
    <category term="railsconf"/>
    <link href="http://www.spacevatican.org/2008/6/10/berlin-here-we-come" rel="alternate" type="text/html"/>
    <title>Berlin, here we come!</title>
<content type="html">
            &lt;p&gt;Hot off the presses: the Railsconf Europe proposal submitted by my colleague Paul Butcher and myself has been accepted! Join us in Berlin to here about &lt;a href=&quot;http://en.oreilly.com/railseurope2008/public/schedule/detail/3557&quot;&gt;the nifty stuff we've been up to&lt;/a&gt;. I can't wait!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-06-08:27</id>
    <published>2008-06-08T17:00:00Z</published>
    <updated>2008-08-01T23:39:17Z</updated>
    <category term="Rails"/>
    <category term="activerecord"/>
    <link href="http://www.spacevatican.org/2008/6/8/dealing-with-concurrency" rel="alternate" type="text/html"/>
    <title>Dealing with concurrency</title>
<content type="html">
            &lt;p&gt;Sometimes you don&#8217;t want a user doing two things at once (or two users doing something to the same third party at once). Dealing with this sort of issue is quite fiddly as its easy to overlook them and hard to track them down when they happen as they tend to be heavily timing dependant&lt;a href=&quot;#note_4&quot;&gt;[4]&lt;/a&gt;. There&#8217;s a few tricks in the rails toolbox for dealing with them. &lt;/p&gt;

&lt;p&gt;There&#8217;s a related issue that this post is not about: suppose two users bring up the edit form for some object. They each make unrelated changes to the form and save, one after the other. The second user will squash the changes made by the first user. Oops. I&#8217;m not concerned about that, only with what happens if the two requests are actually concurrent, whereas here the two save requests could be minutes apart.&lt;/p&gt;

&lt;p&gt;One way of solving this problem is for editable objects to have an edited_by association and disallowing edits if someone else is in the process of editing. Another way is to get clever about how you apply changes to attributes. While not directly relevant, the things outlined here may still be useful, for example if you go down the route of only allowing the user named in the edited_by association to edit the record then you need to be able to reliably set that field even if two users click the edit button at the same time.&lt;/p&gt;

&lt;h2&gt;And now, our feature presentation&lt;/h2&gt;

&lt;p&gt;When I was at school the teacher used to dish out &#8216;bon points&#8217; when you did something good. You could later trade those in for stickers and stuff. In a world very far removed from French primary school classrooms of 1990, the teacher might have written a webapp allowing you to do this (probably complete with an obnoxious facebook app where you could show everyone how many magic stars you have).&lt;/p&gt;

&lt;h2&gt;Optimism&lt;/h2&gt;

&lt;p&gt;The people table has a magic_stars column, and we want people to be able to spend their magic stars on various perks. if someone has been a good boy, you might want to use the credit method:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;credit&lt;/span&gt;
  &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;magic_stars&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;You need to be a little bit careful, as there&#8217;s a race condition here: suppose two people try to give someone a magic star at the same time&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Person 1&lt;/th&gt;&lt;th&gt;Person 2&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;loads child (3 stars)&lt;/td&gt;&lt;td&gt;loads child (3 stars)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;adds 1 &lt;/td&gt;&lt;td&gt;adds 1&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;saves (4 stars)&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;saves (4 stars)&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;The 2 requests execute in separate mongrels (or mod_rails listeners etc&#8230;) and are completely oblivious to each other and will happily overwrite the change made by the other one. Rails&#8217; optimistic locking will help us here: Just add an integer lock_version column to the model (don&#8217;t forget to make it default to 0) and the second &#8216;bad&#8217; save will raise  ActiveRecord::StaleObjectError. We can rewrite our credit method like this:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;credit&lt;/span&gt;
  &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;magic_stars&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;StaleObjectError&lt;/span&gt;
  reload
  &lt;span class=&quot;Keyword&quot;&gt;retry&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;So how does optimistic locking work? The key (unsurprisingly) is in the lock_version column. Assume that we loaded a person object with a lock_version of 4 and we now want to save it. We increment our lock version to 5. If no one else has touched this object then in the database it will still have a lock_version of 4. &lt;/p&gt;

&lt;p&gt;Rails appends &#8220;WHERE lock_version = 4&#8221; to the update query, and then examines the number of rows that were updated (the database driver will return this). If we get 1 then we know everything went ok. If 0 rows were updated then we know that it must have been because someone touched that row and so we raise StaleObjectError. &lt;/p&gt;

&lt;p&gt;Optimistic looking is nice because we&#8217;re not sitting on a database lock at any point, so we won&#8217;t hold up anyone else.&lt;/p&gt;

&lt;h2&gt;Optimism only gets you so far&lt;/h2&gt;

&lt;p&gt;Lets move on to another function: allowing children to swap their magic stars for some sort of perk. We need to check that they&#8217;ve got enough stars and if they do debit the appropriate amount and give them their perk.
This is one of those classic times where you want a transaction: you don&#8217;t want a classroom full of 6 year olds screaming because you took their stars but didn&#8217;t give them their reward. You might write&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;buy&lt;/span&gt; treat
  transaction &lt;span class=&quot;Keyword&quot;&gt;do  &lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; magic_stars &lt;span class=&quot;Keyword&quot;&gt;&amp;gt;=&lt;/span&gt; treat.&lt;span class=&quot;Entity&quot;&gt;cost&lt;/span&gt;
      &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;magic_stars&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;-=&lt;/span&gt; treat.&lt;span class=&quot;Entity&quot;&gt;cost&lt;/span&gt;
      &lt;span class=&quot;Variable&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;treats&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; treat
      save!
    &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;#note_1&quot;&gt;[1]&lt;/a&gt;If something bad happens halfway through then the transaction will roll back all the changes together.&lt;/p&gt;

&lt;p&gt;There&#8217;s a big problem with this code. Suppose the child tries to buy two things in very quick succession. They&#8217;ve got 10 stars to begin with and each item costs 5. If the timing is right, then things will look like this:&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Connection 1&lt;/th&gt;&lt;th&gt;Connection 2&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;start transaction&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Check number of stars&lt;/td&gt;&lt;td&gt;start transaction&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;set number of stars to 5&lt;/td&gt;&lt;td&gt;check number of stars&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;add the treat&lt;/td&gt;&lt;td&gt;set number of stars to 5&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;save&lt;/td&gt;&lt;td&gt;add the treat&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;save&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commit the transaction&lt;/td&gt;&lt;td&gt;commit the transaction&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;The 2 connections walk all over each other. In this case the children will be happy: both connections will set the remaining number of stars to 5, but both items will have been bought!&lt;/p&gt;

&lt;p&gt;So why didn&#8217;t our optimistic locking help? Because of transaction isolation: in most databases by default your transaction won&#8217;t see changes made by other, uncommitted transactions. In fact you won&#8217;t see any changes made after your transaction was started. So when rails tries to save, as far as it can tell the row hasn&#8217;t changed and the save raises no errors.&lt;/p&gt;

&lt;h2&gt;Pessimism&lt;/h2&gt;

&lt;p&gt;The name optimistic locking suggests that there is an alternative, and there is: ask the database to get an actual lock for you. You can do this in two ways in rails: you can pass :lock =&gt; true to a finder (instead of passing true you can pass an sql fragment if you want to change the type of lock acquired) or you can call the lock! method (which is effectively a reload with :lock =&gt; true). It&#8217;s important to note that a lock is held as long as the current transaction. In particular if you aren&#8217;t inside a transaction then nothing happens, or in other words&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;do_something_with_lock&lt;/span&gt;
lock!
do_something
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;doesn&#8217;t accomplish anything at all. Inside a transaction however, you&#8217;ll get an exclusive lock and no other transaction will be able to get a lock for that row. We can rewrite our buy method to look like&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;buy&lt;/span&gt; treat
 transaction &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
   lock!
   ...
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;The lock stops another connection from fiddling with that person at the same time. It&#8217;s just a row lock, so it won&#8217;t stop you editing a different person at the same time&lt;a href=&quot;#note_2&quot;&gt;[2]&lt;/a&gt;. If someone called our credit method from above at the same time that would be ok, as updating the customer row to change the amount of stars they have also requires an exclusive lock, so we&#8217;re in no danger here.&lt;/p&gt;

&lt;p&gt;We can use these locks in more general ways, even if we don&#8217;t want to actually lock the customer row. For example if you have a constraint like a person may only borrow a certain number of books then  you pretty much have to do it in ruby which renders you vulnerable to the various race conditions mentioned before.&lt;/p&gt;

&lt;p&gt;You&#8217;re not modifying any rows (just adding one to a join table), so optimistic locking is no good. You can however lock the person row&lt;a href=&quot;#note_3&quot;&gt;[3]&lt;/a&gt;. You&#8217;re not actually changing it at all, just using the database as a synchronisation method. We can repackage this up as something we can use all over our app:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;exclusive&lt;/span&gt;
  transaction &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    lock!
    &lt;span class=&quot;Keyword&quot;&gt;yield&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Then in your app you can do things like&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
  some_customer.&lt;span class=&quot;Entity&quot;&gt;exclusive&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;    &lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;some task &lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;It should be an easy exercise for the reader to put this in a form where any ActiveRecord model has this exclusive method.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#1_source&quot;&gt;[1]&lt;/a&gt;People sometimes ask about the difference between &lt;code&gt;Person.transaction&lt;/code&gt;, the instance method &lt;code&gt;transaction&lt;/code&gt; and &lt;code&gt;ActiveRecord::Base.transaction&lt;/code&gt;. There is no difference between the first two &#8211; the instance method just calls&lt;code&gt;self.class.transaction&lt;/code&gt;. The transaction method on &lt;code&gt;Person&lt;/code&gt;, &lt;code&gt;ActiveRecord::Base&lt;/code&gt; or some other model class only differ if the models use a different database connection. Most of the time, the three can be used interchangeably.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#2_source&quot;&gt;[2]&lt;/a&gt;If you use a database without row locks (ie mysql with myisam tables) you&#8217;ll probably get something horrible like a table lock.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#3_source&quot;&gt;[3]&lt;/a&gt;Do be careful about deadlocks though.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#4_source&quot;&gt;[4]&lt;/a&gt;The sleep function can be rather helpful when you&#8217;re trying to force particular bits of code to overlap with each other in particular ways.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-05-29:25</id>
    <published>2008-05-29T18:26:00Z</published>
    <updated>2008-05-29T18:27:38Z</updated>
    <category term="Rails"/>
    <category term="&quot;mac os x&quot;"/>
    <category term="rails"/>
    <link href="http://www.spacevatican.org/2008/5/29/squeeze-your-pipes" rel="alternate" type="text/html"/>
    <title>Squeeze your pipes</title>
<content type="html">
            &lt;p&gt;It&#8217;s very easy to merrily write a web application without realising that all those images and ajax calls you&#8217;re using make it rather sluggish when you&#8217;re not just connecting to localhost. Even when you&#8217;ve uploaded it to your production or test servers chances are you&#8217;ll have pretty good bandwidth and latency between you and those servers so it can be hard to see just what it will be like for an enduser who is less well endowed in the broadband department (or even still on dialup).&lt;/p&gt;

&lt;h2&gt;It&#8217;s not just about size&lt;/h2&gt;

&lt;p&gt;Very often it&#8217;s not just about how many bytes a second you could be transfering, the amount of latency is also a critical component of what the app feels like to the end user. Luckily we can simulate both.&lt;/p&gt;

&lt;p&gt;The piece of kit we need is a traffic shaper, a piece of software that sits in between you and the end server and modulates the flow of packets. If you&#8217;re using linux or Mac OS X you&#8217;ve probably already got everything you need. I&#8217;m a mac nerd so I&#8217;ll concentrate on that.&lt;/p&gt;

&lt;p&gt;Luckily it&#8217;s pretty damn easy on the mac as ipfw has all the necessary bits (from 10.4 upwards). The first thing we need to setup is a pipe. To quote the man page, &#8220;A pipe emulates a link with given bandwidth, propagation delay, queue size and packet loss rate&#8221;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
  ipfw pipe 1 config bw 300Kbit/s
  ipfw pipe 2 config bw 500Kbit/s delay 100
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates 2 pipes: one with a bandwidth of 300Kbit/s, and the other with a bandwidth of 500Kbit/s and a propagation delay of 100ms (ie when a packet goes into that pipe it won&#8217;t come out the other end for 100ms)&lt;/p&gt;

&lt;p&gt;Having setup the pipe, you then need to add firewall rules that send traffic through those routes. For example if you&#8217;ve got your mongrel running on port 3000 you can run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
  sudo ipfw add pipe 2 tcp from any to any src-port 3000
  sudo ipfw add pipe 2 tcp from any to any dst-port 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to send traffic to/from port 3000 through pipe number 2. When you&#8217;re done with your testing or if you mess up, run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
  sudo ipfw show
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to show all the firewall rules you&#8217;ve created. The output will look a little like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
00300    72    18982 pipe 2 tcp from any 4500 to any
00400    24     1896 pipe 2 tcp from any to any dst-port 4500
65535 58931 55276029 allow ip from any to any
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first column is the rule number (so 300 and 400 in my case). To remove the rules just run 
&lt;code&gt;sudo ipfw delete rule-number&lt;/code&gt;. This isn&#8217;t the sort of thing I&#8217;d even begin to worry about at the beginning of the project, but worth keeping at the back of your mind.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-05-28:24</id>
    <published>2008-05-28T19:15:00Z</published>
    <updated>2008-05-28T19:17:09Z</updated>
    <link href="http://www.spacevatican.org/2008/5/28/blogging-is-good-for-the-soul" rel="alternate" type="text/html"/>
    <title>Blogging is good for the soul</title>
<content type="html">
            &lt;p&gt;This might not hold true for your vitriolic rants about your ex-girlfriend and similar, but blogging technical content is great. It&#8217;s good for the community in general when there are good howtos, explanations etc&#8230; and I&#8217;m sure a lot of people like the feel of being read by many people, but it&#8217;s not just that.&lt;/p&gt;

&lt;p&gt;It&#8217;s often said that a true test of whether you understand something is whether you can explain it to someone else. Even if you were to erase a blog post the second you finished it, chances are you will have learnt something. I always do, even if I&#8217;m writing about something I already know well. Putting something in the form of a coherent piece of writing pushes me to explore all the edge cases and ramifications which, even I was aware of, hadn&#8217;t fully thought through before.&lt;/p&gt;

&lt;p&gt;So go and write something interesting and do yourself and the community some good. Pick something interesting you worked on recently, a common question or misunderstanding, anything will do!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.spacevatican.org/">
    <author>
      <name>fred</name>
    </author>
    <id>tag:www.spacevatican.org,2008-05-28:19</id>
    <published>2008-05-28T09:17:00Z</published>
    <updated>2008-06-10T09:12:41Z</updated>
    <category term="Rails"/>
    <category term="dependencies"/>
    <category term="plugins"/>
    <category term="rails"/>
    <link href="http://www.spacevatican.org/2008/5/28/reload-me-reload-me-not" rel="alternate" type="text/html"/>
    <title>Reload me, Reload me not</title>
<content type="html">
            &lt;p&gt;Rails&#8217; development&lt;a href=&quot;#note_1&quot;&gt;[1]&lt;/a&gt; mode automatic reloading is pretty nifty. It would really suck having to restart the server everytime you made a change, both in terms of the seconds wasted each time, the manual pressing of buttons you&#8217;d have to do and the 5 minutes wasted here and there when you forgot to restart. There&#8217;s no point reloading rails itself though, so all that stuff stays around. No point reloading plugins either really. I should probably point out that reloading is a misnomer: it implies things are actively loaded (which they aren&#8217;t). What actually happens is sort of that Rails forgets that it has seen Customer and loaded customer.rb, so when it hits Customer it goes off down the const_missing chain and loads your file again.&lt;/p&gt;

&lt;p&gt;Although if you were working on a plugin or trying to diagnose a problem with a plugin it could be useful, but maybe that&#8217;s an edge case. That&#8217;s until your plugin starts to contain something with long lived reference to one of your application&#8217;s classes (or an instance thereof). A classic example is model classes with associations going over the plugin/app boundary. A quick trip to the console shows the problem:&lt;/p&gt;

&lt;p&gt;I&#8217;ve got a teeny tiny app with 2 models: messages and conversations (think forums): conversations have many messages.&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; c &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Conversation&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;first&lt;/span&gt;
=&amp;gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;&amp;lt;Conversation id: 1, title: &amp;quot;hello world&amp;quot;, created_at: &amp;quot;2008-05-28 09:03:58&amp;quot;, &lt;/span&gt;
updated_at: &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;2008-05-28 09:03:58&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; c.&lt;span class=&quot;Entity&quot;&gt;messages&lt;/span&gt;
=&amp;gt; []
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; reload!
&lt;span class=&quot;Variable&quot;&gt;Reloading&lt;/span&gt;...
=&amp;gt; &lt;span class=&quot;Constant&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; c.&lt;span class=&quot;Entity&quot;&gt;messages&lt;/span&gt;
&lt;span class=&quot;Variable&quot;&gt;NoMethodError&lt;/span&gt;: undefined method &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;messages' for #&amp;lt;Conversation:0x1849ccc&amp;gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;reload! makes Rails do its class reloading (a useful trick in itself if you&#8217;re fiddling around at the console and want to see some changes). But what happened? We had a perfectly good instance of conversation and then it got trashed! Lets take a closer look:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; first_class &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;Conversation&lt;/span&gt;
=&amp;gt; &lt;span class=&quot;Variable&quot;&gt;Conversation&lt;/span&gt;(id: integer, title: string, created_at: datetime, updated_at: datetime)
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; first_class.&lt;span class=&quot;Entity&quot;&gt;object_id&lt;/span&gt;
=&amp;gt; &lt;span class=&quot;Constant&quot;&gt;13302014&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; first_class.&lt;span class=&quot;Entity&quot;&gt;instance_methods&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;instance_methods&lt;/span&gt;
=&amp;gt; [&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;message_ids&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;message_ids=&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, ... ]
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; reload!
&lt;span class=&quot;Variable&quot;&gt;Reloading&lt;/span&gt;...
=&amp;gt; &lt;span class=&quot;Constant&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; first_class.&lt;span class=&quot;Entity&quot;&gt;instance_methods&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;instance_methods&lt;/span&gt;
=&amp;gt; []
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Conversation&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;object_id&lt;/span&gt;
=&amp;gt; &lt;span class=&quot;Constant&quot;&gt;13772244&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;So we stash away the conversation class. It&#8217;s got an object id, the methods we would expect, all good. Then we reload! and all the methods are gone. If you ask for Conversation again you get a different class! This is how class reloading of ActiveRecord classes works: the old class is gutted and the constant removed, but we can&#8217;t stop people hanging onto references to the old class &lt;a href=&quot;#note_3&quot;&gt;[3]&lt;/a&gt;(incidentally if you ever get an incomprehensible message about methods not existing when you can see the method definitions right in front of you then you&#8217;ve probably run into a variant of this).&lt;/p&gt;

&lt;p&gt;So if you&#8217;ve got a plugin holding onto a reference to some class, this is what is likely to happen to it, nonsensical messages about methods not existing when they really should. Maddeningly, the first time you load a page it will load fine, but refresh it and it&#8217;s gone! Your tests will pass too, and if you&#8217;re even half sane then your app dying even though the tests pass will give you a bad feeling. If you&#8217;re lucky the only bad thing will be that changes won&#8217;t be noticed until a restart, but even that&#8217;s quite annoying (especially if you didn&#8217;t expect it &#8211; application classes are reloaded after all !).&lt;/p&gt;

&lt;h1&gt;The way out&lt;/h1&gt;

&lt;p&gt;The obvious way out is to reload the plugin as well&lt;a href=&quot;#note_4&quot;&gt;[4]&lt;/a&gt;. The set of things that are loaded only once is controlled by Dependencies.load_once_paths &lt;a href=&quot;#note_5&quot;&gt;[5]&lt;/a&gt;(except for rails itself, that&#8217;s special)  and by default plugin lib directories are added to it. As long as you load via the rails dependency mechanisms, any constant loaded from a path not in that array will be reloaded after a request. This is why a ruby style require of application classes is usually a bad thing: it can stop rails from reloading some of your classes which leads to the problems seen above.&lt;/p&gt;

&lt;p&gt;In my dummy app i&#8217;ve got&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Dependencies&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;load_once_paths&lt;/span&gt;
=&amp;gt; [&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/Users/fred/empty_app/vendor/plugins/dummy_plugin/lib&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]
&lt;/pre&gt;

&lt;p&gt;There&#8217;s an easy way out: in the plugin&#8217;s init.rb just stick &lt;a href=&quot;#note_2&quot;&gt;[2]&lt;/a&gt;&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Support&quot;&gt;Dependencies&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;load_once_paths&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;delete&lt;/span&gt;(&lt;span class=&quot;Support&quot;&gt;File&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;expand_path&lt;/span&gt;(&lt;span class=&quot;Support&quot;&gt;File&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;dirname&lt;/span&gt;(&lt;span class=&quot;Variable&quot;&gt;__FILE__&lt;/span&gt;))&lt;span class=&quot;Keyword&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;/lib&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)
&lt;/pre&gt;

&lt;p&gt;If we boot up our sample app again:&lt;/p&gt;

&lt;pre class=&quot;twilight&quot;&gt;
&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Dependencies&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;load_once_paths&lt;/span&gt;
=&amp;gt; []
&lt;/pre&gt;

&lt;p&gt;Job done!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#1_source&quot;&gt;[1]&lt;/a&gt;None of this applies if config.cache_classes is true (for example in production mode).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#2_source&quot;&gt;[2]&lt;/a&gt;If you load plugins from non standard locations, you may have to fiddle with that: the string you delete m