我有一个通过解析数据文件生成的模型。有几个有趣的值在原始数据文件中不存在,但可以从那些值中获得。
但是,许多这些派生值的计算成本很高,所以我想在计算完成后将它们存储在数据库中。
我试过这个:
def profit
if not self[:profit]
update_attribute :profit, expensive_computation
end
self[:profit]
end
不幸的是,这只能完成一半的工作。计算出的值会被存储,但每次我调用profit时,它都会再次计算该值。
更新:
事实证明问题不在方法中,但在之前的一个find_by_sql语句中,Rails对模型的id感到困惑。我最终得到的代码是:
def profit
unless read_attribute(:profit)
update_attribute(:profit, expensive_computation )
self.save!
end
read_attribute(:profit)
end
答案 0 :(得分:2)
您创建一个新方法并从中删除读取逻辑。也许是这样的
def update_profit
update_attribute :profit, expensive_computation
end
这样你就可以分开阅读逻辑,只需使用方法来获得rails给你的profit
。
@model.profit
其中@model是属性profit
所在的任何类的实例。
答案 1 :(得分:0)
代码应该去哪里取决于何时可以计算利润(例如,一旦记录首次被保存,或者有时会更晚?),以及利润是否可以改变。< / p>
一般情况下,最好将计算放在某种before_create
/ before_save
调用中,只有在可以计算和/或更改时才会保存它
vrish88是正确的,您应该单独保留profit
方法,除非您确实需要在需要时随时计算此数据。如果那真的是你需要的,试试:
def profit
update_attribute(:profit, expensive_computation) unless read_attribute(:profit)
read_attribute(:profit)
end
答案 2 :(得分:0)
这对我来说很好。我的第一个想法是:你在if not self[:profit]
行中有拼写错误吗?
答案 3 :(得分:0)
def profit
super || update_attribute(:profit, expensive_computation)
return super
end
如果利润列中包含信息,只需调用对象的原始利润方法,该方法将从数据库中返回profit
列的内容。
否则,(即profit
列的值为nil
)使用update_attribute
方法计算profit
值并将其存储到数据库中,然后简单地再次从数据库返回值。
如果您已经在数据库中,或者只是profit
,如果昂贵的计算已经运行,那么您希望获得true
的值,只需这样做(update_attribute
返回true或false) :
def profit
super || update_attribute(:profit, expensive_computation)
end