这是一个非常简单的方法(在Rails 4中的Member.rb
中)。
我正在覆盖一个活动记录属性的getter。
def score
self.update(score: compute_score)
super
end
def compute_score
... some unrelated math ...
end
希望这个想法很明确,我试图在每次阅读时更新分数。但是当我运行它时,我陷入了递归循环。 self.update(score: compute_score)
似乎再次调用我定义的自定义score
方法。我还尝试了self.score =
,self[:score] =
和write_attribute
,但产生了相同的结果。我怎样才能避免这种递归?感谢。
答案 0 :(得分:1)
也许尝试update_attribute
ie而不是
self.update(score: compute_score)
尝试:
self.update_attribute(:score, compute_score)
差异是update_attribute
跳过所有验证,我认为这是调用getter的地方。
答案 1 :(得分:1)
如果确实必须在检索记录时更新字段,请在ActiveRecord回调中使用after_initialize
class Member < ActiveRecord::Base
...
after_initialize :compute_score
...
def compute_score
...
end
end
我认为在before_save
计算更好,除非score
取决于某些外部因素(例如第三方API)。如果您必须在检索点进行计算,请使用虚拟属性。