0

各インスタンスに計算量の多いデータを少し保存したい ActiveRecord モデルにインスタンス変数を作成しました...これを行うコードは次のとおりです。

class Account < ActiveRecord::Base

  after_initialize :init
  attr_accessor :market_value

  def init
    self.market_value ||= my_lengthy_function
  end
end

モデルのインスタンスを初期化するときに、そのインスタンス データ (market_value) を実行するためにヒットを取得します。

これは機能します - market_value プロパティを再計算する必要がないことがわかります。

私の問題は、別のコンテキストを介してそのオブジェクトにアクセスすると、レールが期待どおりにそのデータを活用しないことです。

例えば:

アカウントのインスタンスを作成するとします (a = Account.find_by_id(2))。その market_value は、そのオブジェクトに対して 1 回計算されます。

そのアカウント オブジェクトの "holdings" (私のサンプル コードにはありません) と呼ばれる入れ子になった has_many 関係がある場合、これらの各保持オブジェクト (ホールディング) がその親アカウント オブジェクトを使用できるようにする必要があります。

ただし、私のコードでは、ネストされた保持オブジェクト (my_holding.account.market_value) からアカウントにアクセスします。そのアカウント オブジェクトのインスタンスを再インスタンス化すると、既に計算されているにもかかわらず、コストのかかる計算が発生します。

アカウントの market_value プロパティをうまく活用して、再計算を繰り返さないようにするにはどうすればよいですか?

4

2 に答える 2

1

モデルIDをキーとしてクラスレベルで単純なキャッシュを構築します。

class Account < ActiveRecord::Base
  def market_value
    @@market_value     ||= {}
    @@market_value[id] ||= my_lengthy_function
  end
end

ただし、特に開発中のクラスのリロードで、これが機能するかどうかはテストされていません。

于 2012-07-12T17:43:26.317 に答える
1

ActiveRecord モデルには計算ロジックを入れません。多分これらの線に沿った何か:

class MarketValueCalculator

  def initialize()
    @market_values = {}
  end

  def calculate_for_account(account)
    @market_values[account.id] ||= heavy_lifting
  end

  def heavy_lifting
    ###
  end

end

@calculator = MarketValueCalculator.new

@market_value = @calculator.calculate_for_account(account)

@market_value = @calculator.calculate_for_account(my_holding.account)
于 2012-07-13T05:37:48.530 に答える