Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Render collection partial: Getting size of collection inside partial

I have a collection of items I want to render with a partial:

@items = ['a','b','c']

<%= render :collection => @items, :partial => 'item' %>

and I want to number the elements with ascending numbers. So the output should be:

3: a
2: b
1: c

I know rails provides a counter inside the partial, so if I wanted to number the items descending, I could create the following partial:

<%= item_counter %>: <%= item %>

which gives me

1: a
2: b
3: c

But for the ascending numbers, I need the total number of items, which I could provide with a local to the partial:

<%= render :collection => @items, :partial => 'item', :locals => {:total => @items.size} %>

and then in the partial:

<%= total - item_counter %>: <%= item %>

But it feels to me like repetition, because the render method already knows about the size of the collection.

Is there really no way to get the total number of items of a collection inside a partial except using a local variable?

like image 301
Sven Koschnicke Avatar asked Nov 15 '12 12:11

Sven Koschnicke


2 Answers

The following is possible since Rails Version 4.2:

Inside the partial you have access to a function/variable called collection_iteration. Calling collection_iteration.size will give you the total.

From the changelog:

The iteration object is available as the local variable #{template_name}_iteration when rendering partials with collections.

It gives access to the size of the collection being iterated over, the current index and two convenience methods first? and last?.

like image 50
lucasuyezu Avatar answered Sep 21 '22 07:09

lucasuyezu


Ah. Wanted to answer the question. But found correct answer. Anyway here is a tip on future. You can investigate the Rails mechanism with Ruby metaprogramming. For example by calling method 'Kernel#local_variables' in a view which in my case outputs:

[0] = :local_assigns
[1] = :output_buffer
[2] = :row
[3] = :row_counter
[4] = :row_iteration
[5] = :highlighted_description
[6] = :source_description

in case of

  <%= render partial: 'card', collection: @offers, as: :row %>
like image 25
woto Avatar answered Sep 23 '22 07:09

woto