RSS Feed

Counters in partials, a little-known rails feature!

Posted on Tuesday, February 24, 2009 in General

I don’t normally post rails tips that are New To Me, because I always feel like I’m late to the party and everyone knows the tip already. This one however, I vetted through some very experienced rails developers and it was new to them as well. Which is strange, because looking back, I think it was first added in 2004!

The feature I’m talking about is counters in partials used in a collection. Let me show you:

<%= render :partial => “book”, :collection => @books %>

As you know, that will loop through the array of @books and use the template _book.html.erb (by default) each time. Let’s take a look at that file and see how we can use the counter:

<div>
  Number: <%= book_counter %><br/>
  Title: <%= h book.title %><br/>
  Author: <%= h book.author %><br/>
</div>

That will give us output like this:

<div>
  Number: 0<br/>
  Title: Promises in Death<br/>
  Author: J. D. Robb<br/>
</div>

<div>
  Number: 1<br/>
  Title: One Day at a Time<br/>
  Author: Danielle Steel<br/>
</div>

<div>
  Number: 2<br/>
  Title: First Family<br/>
  Author: David Baldacci<br/>
</div>

What’s this useful for?
I can think of two things off the top of my head:

  • Zebra Tables
  • Special classes for first or last elements to change them visually

Let me know here or on twitter (@kastner) if this was helpful (or any other little-known tips)

Bring on the comments

  1. Nice article, however, for Zebra Tables I prefer using the cycle helper, also little known I guess.
    http://api.rubyonrails.com/classes/ActionView/Helpers/TextHelper.html#M001721

  2. Susan Potter says:

    @Dieter I also use and prefer the cycle for zebra tables.

    @Erik thanks! I don’t think I have used this, although I think I *once* saw it in a doc once and then promptly forgot it.

    I am thinking that the case for “special classes for first or last elements to change them visually” is only really useful for “first element” scenario not “last element” or am I missing something? Without passing in more locals to the partial how would you know how many was in the collection?

    Let me know if I am missing something.

    Thanks appreciate the tidbit!

  3. Kastner says:

    You’d have to figure out it’s the last one somehow. One way (although it’s kind of “dirty”) is to just use the collection your iterating over, like this: @books.size == book_counter.

    A cleaner would be to pass the size of the collection in a :local

  4. JohnK says:

    Wow that’s awesome dude, thanks

  5. That was a fantastic article. Exactly what I was looking for. You rock!

  6. RemsAmamp says:

    very intresting

  7. Damien says:

    For the last element it’s quite simple
    just compare your current element with the last of the collection.

    For example:

    if @races.last == race

    Unless your collection is a local variable of the previous view, but I guess it’s not the case.

  8. Kastner says:

    Damien, you can totally do that, but to me it violates separation of concerns – a partial called for a collection shouldn’t know anything about the collection.

  9. linjava says:

    Very nice. Funny, I was actually looking up “rails counter” in google to find your blog posting, but ironically I actually DID need it for a “zebra table”. Perfect! Thanks.

Leave a Reply