Garrett
Garrett

Reputation: 8080

Batch Looping A Model With Ruby

I know of the find_in_batches method for ActiveRecord, but this doesn't allow me to set my :order or :limit.

I am trying to loop through my data, and for every 6 items I want to wrap them in a <div>.

I was trying to whole...

<%
i = 0
@media.each do |media|
%>
<% if i%6 %><div class="section"><% end %>
    [...]
<% if i%6 %></div><% end %>
<%
i += 1
end
%>

But I feel this isn't efficient the "Rails" way. Could I possibly split up my array into 4 different arrays of 6? I am trying to find the best approach to this and was hoping you guys could help.

In the end I need it to come out something like this:

<!--
  I have 24 items in my array, and I need to wrap every 6 inside a div.
-->
<div class="section">
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
</div>

<div class="section">
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
</div>

<div class="section">
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
</div>

<div class="section">
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
   <div class="item"></div>
</div>

Thanks in advance!

Upvotes: 2

Views: 3445

Answers (5)

Benjamin Curtis
Benjamin Curtis

Reputation: 1660

You want in_groups_of:

<% @items.in_groups_of(6) do |group| %>
    <div class="section">
        <% group.each do |item| %>
            <div class="item"></div>
        <% end %>
    </div>
<% end %>

Upvotes: 18

Chuck
Chuck

Reputation: 237080

To answer kind of a side part of your question: You should be able to use find_in_batches along with scopes (either named or anonymous) to set order and limit options.

Upvotes: 2

codeprimate
codeprimate

Reputation: 1376

The most "Rails" like way would be to use the content_tag helper and surround all data with divs, using a specific class for the 6th div.

<% @media.each_with_index do |m, i| %>
  <% content_tag(:div, :class => ( (i % 6==0 )? 'six' : 'other')) do %>
    <%= m %>
  <% end%>
<% end %>  

Upvotes: 0

Michael Sofaer
Michael Sofaer

Reputation: 2947

One thing that would be cleaner:

<% while @media.size > 0 do %>
  <div>
  <%= @media.slice!(0,6).map{|m| m.to_html}.join('</br>')
  </div>
<%end%>

Upvotes: 2

Sinan Taifour
Sinan Taifour

Reputation: 10805

You could start optimizing by using each_with_index instead of each, and <%=..%> instead of the long ifs.

<% @media.each_with_index do |media, i| %>
<%= (i % 6) ? '<div class="section">' : '' %>
    [...]
<%= (i % 6) ? '</div>' : '' %>
<% end %>

Upvotes: 2

Related Questions