Short circuiting partials 5

Posted by Lee Marlow Tue, 15 Aug 2006 16:26:00 GMT

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:
outer page stuff...
<% unless some_object.has_many_things.empty? %>
  <h3>My collection of stuff</h3>
  <%= render :partial => 'my_partial', :locals => { :collection_of_stuff => some_object.has_many_things } %>
<% end %>
more outer page stuff...
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:
outer page stuff...
<%= render :partial => 'my_partial', :locals => { :some_object => some_object } %>
more outer page stuff...
Now it looks like a self-contained component. Good. Of course, we now have to put that outer display logic in the partial.
<% unless some_object.has_many_things.empty? %>
  <h3>My collection of stuff</h3>
  <% some_object.has_many_things.each do |o| %>
    do some stuff with <%= o %>
  <% end %>
<% end %>
Now the messy part is the big unless 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:
def do_something(some_arg)
  return nil unless some_arg
  do_something_cool_with_some_arg
end
Can it be as simple as putting a return statement in our partial? It turns out, yes, it is that easy.
<% return if some_object.has_many_things.empty? %>
<h3>My collection of stuff</h3>
<% some_object.has_many_things.each do |o| %>
  do some stuff with <%= o %>
<% end %>
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.
Comments

Leave a response

  1. Mike Tue, 15 Aug 2006 19:12:21 GMT
    Usually I use the conditional in a partial's outer page to display a message if there aren't any records to render, aka "No entries to display." While your method is obviously a cleaner approach, how would you account for letting the user know that something is wrong instead of just displaying a blank page?
  2. Lee Marlow Tue, 15 Aug 2006 23:09:00 GMT
    Actually, you can return a string instead of just returning. You could also have a block at the top of you page to check for the condition you want, output some message and then call return. You can basically think of the partial as a method that is returning text for output.
  3. Nicholas Wright Wed, 23 Aug 2006 08:56:16 GMT

    That’s the first useful thing I’ve ever gotten from you, Lee.

    Maybe I’ll stop skipping over the posts with your name on them.

    Actually, having typed that, you just arrived at work, and reminded me what you’re like..

  4. wow Thu, 24 Aug 2006 17:51:26 GMT

    u save 1 line… dude its only an end… how much of a deal is that…

  5. Lee Marlow Fri, 25 Aug 2006 08:10:11 GMT

    wow,

    Cutting out one line and a level of indentation is just a pleasant side-effect. I believe the main benefit is the partial has become more of a stand-alone component by consolidating the view logic.

    -Lee

Comments