Question

Currently I am calculating a users balance by

   def balance
      transactions.where('txn_type = ?', Transaction::DEPOSIT).sum(:amount) -    
      transactions.where('txn_type = ?', Transaction::PURCHASE).sum(:amount)
   end

I am running a query that subtracts adds all the users deposits and subtracts all their purchases. This will not scale well when there are thousands of transactions. What would be the best approach to calculating a users balance? Is there a way to customize counter_cache to calculate this per user?

Was it helpful?

Solution

Yes, you can specify :counter_sql which will be used to set the counter_cache.

The rails guide goes into detail about it.

OTHER TIPS

I would suggest two solutions for this

  1. Simple

First add balance column to the User model and Add callback inside Transaction model to update the user's balance based on transaction type.

  1. Complex

If you think you'll also need deposit_amount and purchase amount that too without wasting more time then counter_culture is what you need here.

counter_culture is somewhat similar to rails counter_cache but allow us to do various customizations.

This will involve following changes:

  1. Add counter_culture to your Gemfile:

    gem 'counter_culture', '~> 0.1.33'

then do bundle install

  1. Add columns deposit_amount and purchase_amount to the users table.

    class AddDepositAmountPurchaseAmountToUsers < ActiveRecord::Migration
      def self.change
        add_column :users, :deposit_amount, :decimal, :default => 0
        add_column :users, :purchase_amount, :decimal, :default => 0
      end
    end
    
    then do rake db:migrate

  2. Make appropriate changes to the code

Inside Transaction model

counter_culture :user,
  column_name: Proc.new {|model|
    (model.txn_type == Transaction::DEPOSIT) ? 'deposit_amount' : 'purchase_amount' },
  delta_column: :amount

Inside User model

def balance @balance ||= deposit_amount - purchase_amount end

If you need more information on Counter Culture then please read here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top