Render partial with collection has hidden counter

written by paul on July 20th, 2007 @ 12:50 AM

When rendering a partial with a collection, it can be useful to know the index of the item currently being rendered. It turns out that rails provides this with an undocumented counter.

For example, say we want to render a collection of people who won a contest. We might have a template line like this:


<%= render :partial => "person", :collection => @winners %>

The person partial might look like:


<div>Name: <%= person.name %></div>

Now, let’s say we want to add the person’s rank along with his/her name. Rails provides a local variable called ”#{partial_name}_counter” to provide the index of the currently rendered item in the collection. In our case, the variable is called person_counter. The counter starts at 0, so we’ll add 1 to it for a human readable ranking.

Now, our person partial looks like:


<div>
  Rank: <%= person_counter + 1 %> 
  Name: <%= person.name %>
</div>

And the output is:

Rank: 1 Name: Peter
Rank: 2 Name: Paul
Rank: 3 Name: Mary

Update (6/20/08): Jan points out in the comments that the counter now starts at 1 in Rails 2.1.

Comments

  • John on 30 Jul 08:42

    Hey, thanks for the tip!! I was looking for information on this and found your blog!
  • Joakim on 09 Nov 00:33

    Thanks! This made my day!
  • Alastair on 31 Dec 17:10

    Thanks for the post! Rails has a few 'undocumented features' that I wish were documented.
  • JN2 on 08 Jan 08:14

    Thanks Paul, you're a star!
  • Fernando on 28 Apr 22:15

    Thank very much for sharing hidden knowledges.
  • Jan on 02 Jun 12:28

    Seems like this is broken in Rails 2.1. The counter starts with 1 now, bug or feature?
  • Jan on 02 Jun 13:29

    Feature: http://www.ruby-forum.com/topic/154897#682999
  • daniel on 20 Aug 21:57

    thanks! just what i was looking for :-) i need a way to index my checkboxes that are rendered by the partial and this seems like a perfect/natural way to do it...
  • TobyM on 05 Oct 00:13

    Looks like the counter is back to starting at 0 in Rails 2.1. See http://rails.lighthouseapp.com/projects/8994/tickets/344-partial-counters-start-from-1-in-2-1 for the discussion.
  • Dan on 28 Nov 09:00

    This is exactly what I needed. Thanks for sharing!
  • Joe on 14 May 10:34

    Awesome, thanks so much!
  • Fabian on 27 Nov 10:31

    Thank you very very much!!
  • Javier on 10 Dec 07:13

    Thanks a lot! Great tip!!
  • Mike Jarema on 14 Jan 10:36

    Thanks for the tip. I can confirm this is still working in Rails 2.3.2 and has saved me a bit of hacking to replace, in one of my views, an each_with_index loop with a partial. Mike Jarema
  • Apie on 04 Jun 10:05

    Thanks! This was a great help.
  • Eduardo on 11 Aug 09:24

    This does not work when you apply pagination, because the counter restarts at each page. Does anybody has a elegant solution ?
  • Eduardo on 11 Aug 20:24

    Don't mind, I did solve the pagination problem.
  • Tom on 27 Aug 17:06

    Good article, thanks. One note: if you use the :as flag, (e.g. render :partial => "product", :collection => @products, :as = :pet_product), then the _counter suffix only works for product, not the as alias. :product_counter #works! :pet_product_counter #doesn't!

Post a comment

Options:

Size

Colors