mr_muscle
mr_muscle

Reputation: 2900

Ruby/Rails 6 summation during iteration

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

Answers (1)

Gaurav Patil
Gaurav Patil

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

Related Questions