March 18, 2008

Posted by John

Tagged partials

Older: Google Analytics Fun

Newer: Twitter Gem Gets STDIN

A Few Helpful Helpers

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 Comments

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

  2. Steven Garcia Steven Garcia

    Mar 19, 2008

    Care to share the actual helper code? :)

  3. @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. 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. @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. @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. Nice post, thank you!

  8. 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. @Matt Aimonetti – I’ll be quicker next time. :)

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

  11. nice work, bro

Sorry, comments are closed for this article to ease the burden of pruning spam.

About

Authored by John Nunemaker (Noo-neh-maker), a programmer who has fallen deeply in love with Ruby. Learn More.

Projects

Flipper
Release your software more often with fewer problems.
Flip your features.