Hey all I have a block of code that utilises 3 models...
class Buyer < ActiveRecord::Base
has_many :trans
has_many :sellers, :through => :trans
There are 2 ways I see that you can do this. The simpler approach (albeit less efficient in the sorting), would be to aggregate the sums by buyer_id
and then inject that into the list of buyers:
<% buyer_sums = @seller.trans.group(:buyer_id).sum(:sum) %>
<% Buyer.where(id: buyer_sums.keys).sort_by {|b| -buyer_sums[b.id]}.each do |buyer| %>
<%= buyer.name %> <%= buyer_sums[buyer.id] %>
<% end %>
A second approach would be to fetch the sums together with the buyer:
<% Buyer.joins(:trans).merge(@seller.trans).
select("buyers.*, SUM(`sum`) sums").order('SUM(`sum`)').each do |buyer| %>
<%= buyer.name %> <%= buyer.sums %>
<% end %>
The advantage of the second approach is that you aren't sorting after retrieving the entire collection, which matters for scalability especially as related to pagination.
Note that the backtick (`) escape character used here is for MySQL, but should be replaced with the appropriate DB convention if otherwise (e.g. double quote for PostgreSQL). Alternatively, use the quote_column_name
method to do this smarter :)