UserとTrainingSessionの2つのモデルがあります。
class User < ActiveRecord::Base
has_many :training_sessions
end
class TrainingSession < ActiveRecord::Base
belongs_to :user
end
各ユーザーは、(TrainingSessionモデルで)累積されたtraining_sessionsの期間の合計に基づいて、特定の数のポイントを持ちます。
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属性を最新の状態に保つにはどうすればよいですか?