2

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属性を最新の状態に保つにはどうすればよいですか?

4

1 に答える 1

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
于 2012-09-06T02:57:00.993 に答える