如何在子模型中使用after_save回调来更新父模型中的属性?

时间:2012-09-06 02:25:23

标签: ruby-on-rails-3 callback parent-child

我有两个模型,User和TrainingSession:

class User < ActiveRecord::Base
has_many :training_sessions
end

class TrainingSession < ActiveRecord::Base
belongs_to :user
end

每个用户根据累积的training_sessions持续时间总和(在TrainingSession模型中)有一定数量的积分

class TrainingSession
def points
  sum(:duration) / 6
end

目前,在用户创建新的training_session之后,我将更新User模型中的points属性,如下所示(来自TrainingSession控制器):

# POST /training_sessions
# POST /training_sessions.json
def create
@user = User.find_by_id(session[:user_id])
@training_session = @user.training_sessions.new(params[:training_session])
@points = @user.training_sessions.points
@user.update_attribute(:points, @points)
...

问题是每次创建training_session时,它都不会包含用户从最近创建的training_session中产生的积分。例如,如果用户有160分,那么他们将进行60分钟的运行,他们将获得10分以达到170分。但是在创建60分钟运行training_session之后,用户模型将其更新为160分。所以它总是落后一步,可以这么说。我尝试在TrainingSession模型上使用after_save回调,如下所示:

class TrainingSession < ActiveRecord::Base
after_save :update_points  

private

def update_points
 count = @user.training_sessions.sum(:duration)
 if count >= 1
  points = count / 6
 end
 @user.update_attribute(:points, points)
end

但是在尝试创建新的training_session时我遇到了这个错误:

undefined method `training_sessions' for nil:NilClass

所以,我的问题是,我如何通过包含最近创建的training_session来跟上我的用户模型的:points属性?

1 个答案:

答案 0 :(得分:3)

您的模型中未定义

@user。这就是你得到错误的原因。

培训会话属于用户,因此在您的模型中,您可以通过self.user或仅user来获取用户。这段代码应该有效:

def update_points
  count = self.user.training_sessions.sum(:duration)
  points = count / 6 if count >= 1
  self.user.update_attribute(:points, points)
end