我在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属性,以便不会重新计算?
答案 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)