2013-10-10 27 views
0

我有一个User模型,其中has_many :scoreshas_many上的更新应更新父类上的属性

如果我添加一个:分给用户,用户应该做的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

(它不是一个countercache列,方法也更复杂,只是在这里勾勒)

千恩万谢

回答

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 
+0

嗨安德鲁的工作,感谢您的回复。我有另一种方法解决了我的问题。 – Jan

+0

如果您直接创建乐谱 - 即Score.create(user_id:1,value:123),我认为您的解决方案不会奏效,因为它不会更新父项,并触发用户级别更新。 –

0

我找到了与

after_create :set_level 

def set_level 
    self.update_attribute :level, calculate_level 
end