Rails counter_cache Balance

时间:2012-04-30 15:27:28

标签: ruby-on-rails ruby-on-rails-3 activerecord counter-cache

目前我正在按

计算用户余额
   def balance
      transactions.where('txn_type = ?', Transaction::DEPOSIT).sum(:amount) -    
      transactions.where('txn_type = ?', Transaction::PURCHASE).sum(:amount)
   end

我正在运行一个减去的查询,添加所有用户的存款并减去他们的所有购买。当有数千笔交易时,这将无法很好地扩展。计算用户余额的最佳方法是什么?有没有办法自定义counter_cache来计算每个用户?

2 个答案:

答案 0 :(得分:2)

是的,您可以指定:counter_sql,用于设置counter_cache

rails guide详细介绍了它。

答案 1 :(得分:0)

我会建议两个解决方案

  1. 简单
  2. 首先将balance列添加到用户模型和 在Transaction模型中添加回调,以根据事务类型更新用户的余额。

    1. 复合
    2. 如果您认为自己也需要deposit_amountpurchase amount而且不会浪费更多时间,那么counter_culture就是您所需要的。

      counter_culture有点类似于rails counter_cache但允许我们进行各种自定义。

      这将涉及以下更改:

      1. 将counter_culture添加到您的Gemfile:

        gem'counter_culture','〜> 0.1.33'

      2. 然后执行bundle install

        1. 将列deposit_amountpurchase_amount添加到users表。

          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. 对代码进行适当的更改

        3. 内部交易模型

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

          内部用户模型

          def balance @balance ||= deposit_amount - purchase_amount end

          如果您需要有关反文化的更多信息,请please read here