It will perform better getting the correct data directly from the db:
@products = @line_items.group(:name).order("count_all DESC").count
That will give you the names and counts directly, e.g.
# => { "line_1" => 3, "line_2" => 2, "line_3" => 8 }
There's a bit of Rails magic at work here: the SQL generated using group
, order
and count
will look like:
SELECT COUNT(*) AS count_all, name AS name FROM spree_line_items GROUP BY name ORDER BY count_all DESC
That's where count_all
comes from: Rails attaches it to the count column automatically.
Then you can plug this directly into your view:
<% @products.each do |name, line_item_count| %>
<%= name %> - <%= line_item_count %><br>
<% end %>
Alternatively, if you're using the instance variable elsewhere, here's a simple Ruby solution:
@products = @line_items.group_by(&:name).sort_by { |_k, line_items| line_items.count }.reverse
This simply uses sort_by
to get records ordered by the relevant count, then reverses to get decending order. There's a good benchmark on doing this here.
Hope that helps - let me know how you get on / if you've any questions.