<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>OnRails.org: Tag components</title>
    <link>http://onrails.org/articles/tag/components?tag=components</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Ruby On Rails and related matters.</description>
    <item>
      <title>Short circuiting partials</title>
      <description>I tend to think of partials as mini-components.  I don't like it when the page using the partial "knows" too much about what's in the partial.  For instance, if your partial displays a collection of things but shouldn't display anything if the collection is empty, then you'll usually see something like this:

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&lt;notextile&gt;outer page stuff...
&amp;lt;% unless some_object.has_many_things.empty? %&amp;gt;
  &amp;lt;h3&amp;gt;My collection of stuff&amp;lt;/h3&amp;gt;
  &amp;lt;%= render :partial =&amp;gt; 'my_partial', :locals =&amp;gt; { :collection_of_stuff =&amp;gt; some_object.has_many_things } %&amp;gt;
&amp;lt;% end %&amp;gt;
more outer page stuff...&lt;/notextile&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

The outer page has to know which collection of things the partial is going to use and performs some display logic around that.  Shouldn't this all be contained in the partial?  The outer page should just know that it is going to use a partial and that's it.  So our outer page will look like this:

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&lt;notextile&gt;outer page stuff...
&amp;lt;%= render :partial =&amp;gt; 'my_partial', :locals =&amp;gt; { :some_object =&amp;gt; some_object } %&amp;gt;
more outer page stuff...&lt;/notextile&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Now it looks like a self-contained component.  Good.  Of course, we now have to put that outer display logic in the partial.

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&lt;notextile&gt;&amp;lt;% unless some_object.has_many_things.empty? %&amp;gt;
  &amp;lt;h3&amp;gt;My collection of stuff&amp;lt;/h3&amp;gt;
  &amp;lt;% some_object.has_many_things.each do |o| %&amp;gt;
    do some stuff with &amp;lt;%= o %&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/notextile&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Now the messy part is the big &lt;code&gt;unless&lt;/code&gt; block around the whole partial.  I'd like to just short circuit the whole page if there's nothing to display, similar to what I do in normal methods:

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&lt;notextile&gt;def do_something(some_arg)
  return nil unless some_arg
  do_something_cool_with_some_arg
end&lt;/notextile&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Can it be as simple as putting a &lt;code&gt;return&lt;/code&gt; statement in our partial?  It turns out, yes, it is that easy.

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&lt;notextile&gt;&amp;lt;% return if some_object.has_many_things.empty? %&amp;gt;
&amp;lt;h3&amp;gt;My collection of stuff&amp;lt;/h3&amp;gt;
&amp;lt;% some_object.has_many_things.each do |o| %&amp;gt;
  do some stuff with &amp;lt;%= o %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/notextile&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Wow!  One whole line shorter.  It doesn't look like much in this small contrived example, but I think it makes the purpose of the partial clearer and doesn't clutter up the calling page.  Give it a shot.</description>
      <pubDate>Tue, 15 Aug 2006 16:26:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:bb8436b2-87db-4382-bdf9-e61505efcb04</guid>
      <author>Lee Marlow</author>
      <link>http://onrails.org/articles/2006/08/15/short-circuiting-partials</link>
      <category>Rails</category>
      <category>partials</category>
      <category>components</category>
      <category>views</category>
    </item>
  </channel>
</rss>
