has_many上的更新应该更新父类的属性

时间:2013-10-10 14:30:01

标签: activerecord ruby-on-rails-3.2

我有一个User模型has_many :scores

如果我向用户添加:score,则用户应重新计算playcounter:

class User < ActiveRecord::Base

  has_many :scores, inverse_of: :user

  accepts_nested_attributes_for :scores

  attr_accessible :level

  before_save: set_levels

  def set_levels
    self.level = calculate_level
  end

  def calculate_level
    self.scores.count
  end

end

当我通过User.score.create(:time => 10)添加分数时,分数会被保存,但等级不会更新。

如果附加了孩子,我该如何重新运行set_levels

(这不是一个反向缓存列,方法更复杂,只是在这里草拟)

非常感谢

2 个答案:

答案 0 :(得分:0)

您需要向Score模型添加一个回调,可能是分数模型上的after_commit,以告知父User重新计算该等级。

class Score < ActiveRecord::Base
  after_commit do
    # can just call touch, as before_save will calc
    user.touch
  end
end

现在,只有您想要在每个分数上重新计算并同步。 更多时候我会删除一条消息,例如resque / sidekiq,这样做,所以我的分数创建/更新很快。

class Score < ActiveRecord::Base
  after_commit do
    UpdateUserLevelWorker.perform_async(user_id)
  end
end

class UpdateUserLevelWorker

  include Sidekiq::Worker

  def perform(user_id)
    # can just call touch, as before_save will calc
    User.find(user_id).touch
  end
end

答案 1 :(得分:0)

我已经使用了

after_create :set_level

def set_level
  self.update_attribute :level, calculate_level
end