活动记录模型上的实例变量

时间:2012-07-12 17:37:55

标签: ruby-on-rails activerecord instance-variables

我在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属性。

我的问题是,当我通过另一个上下文访问该对象时,rails并没有像我期望的那样利用这些数据。

例如:

假设我创建了一个帐户实例(a = Account.find_by_id(2))。该market_value将在该对象上计算一次。

如果我在该帐户对象上有一个名为“馆藏”(不在我的示例代码中)的嵌套has_many关系,我会希望每个持有对象(持有)能够使用它的父母帐户对象。

但是,在我的代码中,我从它的嵌套保存对象(my_holding.account.market_value)访问该帐户 - 我重新实例化该帐户对象的实例,并导致代价高昂的计算,即使它已经被计算过。

如何更好地利用该帐户的market_value属性,以便不会重新计算?

2 个答案:

答案 0 :(得分:1)

我会在类级别上构建一个简单的缓存,并将模型ID作为键:

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

未经测试是否可行,尤其是在开发中重新加载类。

答案 1 :(得分: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)