A Few Helpful Helpers

March 18th, 2008

There are a few view related things of late I’ve been using to make my code a bit more readable. Trust me, they are nothing new, but for whatever reason I hadn’t jumped on the train.

div_for

This doesn’t do anything special but saves some typing and I tend to think it makes things a bit more aesthetically pleasing in TextMate. Using div_for, the following:

<div id="<%= dom_id attachment %>" class="<%= dom_class attachment %>">
    ... removed for clarity ...
</div>

becomes..

<%- div_for attachment do -%>
    ... removed for clarity ...
<%- end %>

You can also use it’s companion, content_tag_for in the case where you are creating table rows or something:

<%- content_tag_for :tr attachment do -%>
    <td>... removed for clarity ...</td>
<%- end %>

local_assigns

Want to pass in optional parameters to a partial rendering? local_assigns is the key to your problems.

<%- if local_assigns.has_key?(:show_project) -%>
    <h3><%= time_entry.project.name %></h3>
<%- end -%>

If you did <%= render :partial => 'foo', :locals => {:time_entry => time_entry, :show_project => true} %>, the project heading would be shown but if you just did <%= render :partial => 'foo', :locals => {:time_entry => time_entry} %> without the :show_project hash key, the heading would not be printed. That might be a bad example, but you get the idea.

content_tag

Obie mentioned a good use for this in the Rails Way, which is in combo with an if statement for some one line goodness. Take the following for example:

<%- if current_user.authorized_to_edit?(user) -%>
    <span class="actions">
        <%= link_to 'Edit', edit_user_path(user) %>
    </span>
<%- end -%>

That works ok, but using content_tag you can easily put it on one line like so:

<%= content_tag 'span', link_to('Edit', edit_user_path(user), :class => 'actions') if current_user.authorized_to_edit?(user) %>    

The two examples put out the same html with the same permissions but the latter is much more succinct.

debug

In PHP, it was var_dump. In ColdFusion is was <cfdump>. Somehow, I overlooked debug in rails for almost a year. Simply call <%= debug @projects %> in your view and you will get a to_yaml representation of the variable wrapped in pre tags.

I’m sure there are tons of others that I’m not super aware of, but these are a few that I’ve found helpful of late. Anybody have other favorites? Maybe concat mixed with a block? Maybe some capture action?

11 Responses to “A Few Helpful Helpers”

  1. Rob Sanheim Says:

    For local assigns, couldn’t you just use defined? For example: if defined?(show_project) && show_project ?

  2. Steven Garcia Says:

    Care to share the actual helper code? :)

  3. John Nunemaker Says:

    @Rob – Hmm…well everything I’ve read says defined? won’t work in partials due to the limitations of the rendering system. I thought I’ve tried and failed with it before as well. I might have to confirm that.

    @Steve – These are all in rails core, nothing special that I’ve created. Check out ActionView::Helpers.

  4. Robby Russell Says:

    I’m not a big fan of the content_tag usage that you showed. While you can squeeze everything into one line, this doesn’t improve readability of the view. We once decided to start using this for a lot of helpers and when our HTML/CSS people started to have to make changes they had to spend too much time digging around in Rails to find the corresponding HTML.

    I’d argue that in the long run (as we’ve seen)... this adds unnecessary complexity for the sake of saving a few lines of code.

    As Martin Fowler once wrote… “Remember your code is for a human first and a computer second.” =)

  5. jc Says:

    @Rob. “defined?” does NOT work reliably in partials. It’s really important that people know about local_assigns, as its not documented very well and everyone tries to use “defined?” or “respond_to?” which causes all sorts of problems.

    Thanks John for the great tips

  6. John Nunemaker Says:

    @Robby – I don’t do it to save on lines. I think it is more readable than seeing a crap load of if statements in your views. Just my preference.

  7. Sebastian Says:

    Nice post, thank you!

  8. Matt Aimonetti Says:

    I have to say that I didn’t know about local_assigns and I wish I you posted about this helper few days earlier ;)

    defined? and respond_to don’t work reliably in partials, local_assigns seems to be the solution to my problems.

    Thanks

  9. John Nunemaker Says:

    @Matt Aimonetti – I’ll be quicker next time. :)

  10. Erik Says:

    I like helpers so much, it is one of the best thing in rails right now for me :)

  11. nidaPiefnida Says:

    nice work, bro

Sorry, comments are closed for this article.