Jul 202007

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:

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

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.

  21 Responses to “Render partial with collection has hidden counter”

  1. Hey,
    thanks for the tip!! I was looking for information on this and found your blog!

  2. Thanks! This made my day!

  3. Thanks for the post! Rails has a few ‘undocumented features’ that I wish were documented.

  4. Thanks Paul, you’re a star!

  5. Thank very much for sharing hidden knowledges.

  6. Seems like this is broken in Rails 2.1. The counter starts with 1 now, bug or feature?

  7. 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…

  8. 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.

  9. This is exactly what I needed. Thanks for sharing!

  10. Awesome, thanks so much!

  11. Thank you very very much!!

  12. Thanks a lot! Great tip!!

  13. 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

  14. Thanks! This was a great help.

  15. This does not work when you apply pagination, because the counter restarts at each page. Does anybody has a elegant solution ?

  16. Don’t mind, I did solve the pagination problem.

  17. 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!

  18. Awesome – I love these little tips that just makes rails so cool.

    Thanks for contributing it!

  19. @Eduardo – the pagination issue does reset the counter, how can the original page’s index or counter total be copied over to the next page? I need to pass the value somehow..

  20. The counter has been reset back to 0 from rails 3.0 now :)

Sorry, the comment form is closed at this time.