Reputation: 2900
I've got an App in which User
can buy shares in a Portfolio
through a wallet.cash_transaction
. Now I would like to display all shareholders of the portfolio specifying the user's name and the number of shares in a given portfolio.
#models association
class User < ApplicationRecord
has_one :wallet, as: :walletable
has_many :cash_transactions, through: :wallet
end
class Portfolio < ApplicationRecord
has_one :wallet, as: :walletable
end
class Wallet < ApplicationRecord
belongs_to :walletable, polymorphic: true
has_many :cash_transactions
end
class CashTransaction < ApplicationRecord
belongs_to :wallet
belongs_to :to_wallet, class_name: 'Wallet', optional: true
end
To display shareholders I'll need below join:
> portfolio = Portfolio.last
@shareholders = User.joins(:cash_transactions).where(cash_transactions: { to_wallet: portfolio.wallet }).uniq
Which I can use in the view by below iteration:
<tbody>
<% @shareholders.each do |user| %>
<tr>
<td><%= "#{user.first_name} #{user.last_name}" %></td>
<td><%= user.cash_transactions.where(to_wallet: portfolio.wallet).sum(:shares_number) %></td>
</tr>
<% end %>
</tbody>
Line user.cash_transactions.where(to_wallet: portfolio.wallet).sum(:shares_number)
is responsible for the summation of all user shares in the portfolio. This method doesn't seem very efficient to me because it seems like I'll be sum-up unnecessarily at each iteration. I imagine that when there will be hundreds of thousands of users it can be aggravating at every refresh of the page. Is there a better way to do so?
Upvotes: 0
Views: 57
Reputation: 1382
You can write SQL queries to get sum of all matched records
@shareholders = User.joins(:cash_transactions)
.where(cash_transactions: { to_wallet: portfolio.wallet})
.select("users.*, SUM(cash_transactions.shares_number) as total_shares_number")
.group("users.id")
you will get all columns of users
table and sum of total shares_number
, Add more fields form another table as per your requirement
Upvotes: 2