Reputation: 921
I currently am using this peice of code to loop through ordered items for a specific date
<tr>
<th>Item</th>
<th>Quantity</th>
</tr>
<% @demand.each do |d| %>
<% d.demand_items.each do |item| %>
<tr>
<td><%= item.item.name %></td>
<td><%= @item_count %></td>
</tr>
<% end %>
<% end %>
Currently if item 1 is ordered more than once, it shows up multiple times in the list. I just want it to show up once and have a number next to it to show how many are ordered. For example, if item_1 has a quantity of 5 in demand_1 and item_1 has a quantity of 10 in demand_2, the result should be:
item_1 .... 15
Thanks!
Upvotes: 3
Views: 852
Reputation: 54882
This should do it:
<tr>
<th>Item</th>
<th>Quantity</th>
</tr>
<% @demand.flat_map(&:demand_items).group_by(&:item).each do |item, demands| %>
<tr>
<td><%= item.name %></td>
<td><%= demands.map(&:quantity).inject(:+) %></td>
</tr>
<% end %>
Hope this helps!
Some explanation:
@demand.flat_map(&:demand_items)
# equivalent: (long version)
@demand.map{ |demand| demand.demand_items }.flatten
# retrieves all demand_items of each demand in the @demand list
# flatten the result (which is a double-dimension array)
demands.map(&:quantity)
# sends .quantity call to each element of the demands list
# and put it in an array (so this returns an array of quantity of each demand)
# equivalent: (long version)
demands.map{ |demand| demand.quantity }
demands.map(&:quantity).inject(:+)
# the inject(:+) will inject the method + (add) between each element of the array
# since the array is a list of quantities
# the inject(:+) sums each quantity of the list
Upvotes: 3
Reputation: 96504
I would try and get the uniq items and then count them while looping, something like:
(@demand.demand_items.sort.uniq).each do |d|
d.item_name
d.demand_items.count
end
This is untested pseudo code.
Upvotes: 2