0

I'm trying to render a bulk of content in rows of three. However, I'm not sure how would I determine the current position of the element using Ruby. This is what I have:

<% Animals.each do | animal | %> <%= animal.species %> <% end %> 

I want to be able to add a <BR> or if I was rendering a table a </TR><TR> each time we'd hit the third animal in the set. Of course, if the number of elements nE isn't divisible by three, then the table would be malformed. I figured by doing a bit of checking after the iteration that I could close it.

But is there a way to get the index of an element that's being iterated over in an Array.each method? I have the strong hunch that I could just do the following:

<table> <% Animals.each do | animal | %> <% if Animals.find_index(animal) / 3 == 0 %> <tr> <% end %> <td><%= animal.species %></td> <% if Animals.find_index(animal) / 3 == 2 %> </tr> <% end %> </table> 

My only thing is that Animal is a subclass of ActiveRecord::Base, so I'm not sure (haven't looked to see) if this would scale well, let alone if each call to find_index would be a super intensive method. Any suggestions are welcome.

2
  • I'm using Ruby 1.9.3 and according to apidock.com/ruby/Enumerable/Enumerator/each_with_index that method isn't available in that version. However, this would have done the job! Commented Jul 26, 2012 at 18:10
  • 1
    That method is available. It was only moved to a different part of Enumerable and since Array inherits from it, the method is still available to Array. Commented Jul 26, 2012 at 18:19

1 Answer 1

4

You need

<% animals = Animals.all %> <table> <% animals.in_groups_of(3) do |animal_row| %> <tr> <% animal_row.compact.each do |animal| %> <td><%= render animal %></td> <% end %> </tr> <% end %> </table> 

Should roughly do the job.

More importantly, I think keeping the Enumerable module's documentation handy has been great for me as a Ruby developer. It is my "favourite" module, and nearly ALWAYS helps me solve tricky problems easily.

Sign up to request clarification or add additional context in comments.

5 Comments

Talk about a quick reply! Thanks!
Notice how i've used compact in the inner loop. It is critical becase that the last group of 3 may not contain exactly 3 elements (when the total elements are not divisible by 3). The last set is padded with nils and compacting the last sent saves you from nil errors.
I was going to ask why, but then you read my mind! Thank you again :D
I pre-empted your question :)
Not much of a difference but, animals.in_groups_of(3, false) will get rid of the extra nils so you won't have to use compact later.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.