我想在完成锻炼后更改Users表中的用户workout_id。我无法弄清楚如何做到这一点。以下是我试图弄清楚的两种方法。
尝试1:在控制器中放置一个if语句,当true为增量时,用户workout_id - 问题是if语句只在条件已经为真时才通过,所以用户需要尝试在锻炼结束后完成额外的锻炼。
示例:
def create
@completed_set = CompletedSet.new(params[:completed_set])
if @totalExercisesInWorkout.included_in?(@completedExercises) == true
raise "it worked!"
end
respond_to do |format|
if @completed_set.save
format.html { redirect_to profile_path, notice: 'Successfully completed set.' }
format.json { render json: @completed_set, status: :created, location: @completed_set }
else
format.html { render action: "new" }
format.json { render json: @completed_set.errors, status: :unprocessable_entity }
end
end
end
尝试2 使用模型中的after_save
回调。 - 这不起作用,因为我无法访问模型中的会话信息,因此我无法知道用户是什么,他们的workout_id是什么,以及他们是否已完成锻炼。
这个问题必须有一个简单的解决方案,但我完全难过!
谢谢!
编辑:
当具有锻炼的exercise_id的数组与用户的completed_set exercise_is的数组匹配时,锻炼完成。因此,当以下代码为真时:
@totalExercisesInWorkout.included_in?(@completedExercises)
.include_in?是Array Class的扩展,如果第二个数组包含第一个数组中的所有值,则返回true。
锻炼has_many
练习
当用户“完成”锻炼时,该锻炼和相关信息(例如user_id,workout_id等)存储在completed_set表中。
在我的application_controller
我有一个initialize_vars
方法,可以找到我需要了解的有关用户及其锻炼的所有信息。这是:
def initialize_vars
@workout = Workout.find(current_user.workout_id)
@user_program = current_user.program
@user_cycle = Cycle.find(current_user.cycle_id)
@user_group = Group.find(current_user.group_id)
@exercise = @workout.exercises
@workout_exercise = @workout.workout_exercises
# Array needs to have an exercise for every set in the exercise
@exercisesInWorkout = @workout.exercises.pluck(:exercise_id)
# Array of the sets in the users current workout
@workoutSets = @workout_exercise.pluck(:sets)
# Array of exercises user has completed in current workout
@completedExercises = CompletedSet.where(:user_id => current_user.id).pluck(:exercise_id)
# Array of exercise_id's in workout times the number of sets for each exercise
@totalExercisesInWorkout = @exercisesInWorkout.zip(@workoutSets).map { |n1, n2| [n1] * n2 }.flatten
#Total number of reps a user has completed
@repsCompleted = CompletedSet.where(:user_id => current_user.id).pluck(:repetitions).sum
#Total amount of weight a user has lifted
@weightLifted = CompletedSet.where(:user_id => current_user.id).pluck(:weight).sum
end
编辑2:
我在这里学到了很多东西。我重构了我的代码。这就是现在的样子。
Class User
def cycle
Cycle.find(cycle_id)
end
def group
Group.find(group_id)
end
def workout
Workout.find(workout_id)
end
def completed_exercise_ids_array(user)
CompletedSet.where(workout_id: workout_id, user_id: user).pluck(:exercise_id)
end
def sets_in_workout_array
workout.workout_exercises.pluck(:sets)
end
def exercises_in_workout_times_sets_array
workout.workout_exercises.pluck(:exercise_id).zip(sets_in_workout_array).map { |n1, n2| [n1] * n2 }.flatten
end
def update_workout_if_needed!
if exercises_in_workout_times_sets_array.included_in?(completed_exercise_ids_array)
self.workout.id = self.workout.next_workout_id
save!
end
end
# Methods for progress area
def total_reps_completed(user)
CompletedSet.where(user_id: user).sum(:repetitions)
end
def total_weight_lifted(user)
CompletedSet.where(user_id: user).sum(:weight)
end
我的application_controller
class ApplicationController
# Application wide instance variables go here. Just don't forget to call initialize_vars in the controllers you want to call these variables in.
def initialize_vars
@user_workout = current_user.workout
@user_cycle = current_user.cycle
@user_group = current_user.group
@exercise = @user_workout.exercises
# Array of the sets in the users current workout
@workoutSets = current_user.sets_in_workout_array
# Array of exercises user has completed in current workout
@completedExercises = current_user.completed_exercise_ids_array(current_user)
# Array of exercise_id's in workout times the number of sets for each exercise
@totalExercisesInWorkout = current_user.exercises_in_workout_times_sets_array
end
我将一些逻辑移到了profile_controller
答案 0 :(得分:1)
对于CompletedSet的after_create
回调将是最佳选择:
class CompletedSet < ActiveRecord::Base
belongs_to :user
belongs_to :workout
belongs_to :exercise
after_create :update_user_workout
def update_user_workout
user.update_workout_if_needed!
end
end
class User < ActiveRecord::Base
has_many :completed_sets
belongs_to :workout
def completed_exercise_ids
completed_sets.where(workout_id: workout_id).pluck(:exercise_id)
end
def update_workout_if_needed!
if completed_exercise_ids.included_in?(workout.workout_exercises.pluck(:exercise_id))
self.workout = Workout.next(workout)
save!
end
end
end
class Workout < ActiveRecord::Base
has_many :workout_exercises
has_many :exercises, through: :workout_exercises
# some logic to determine the next workout - modify as needed
def self.next(workout)
where("workouts.sequence > ?", workout.sequence).order(:sequence).first
end
end
此解决方案假设您已将current_user
与控制器create
操作中的CompletedSet相关联(我没有看到):
def create
@completed_set = current_user.completed_sets.build(params[:completed_set])
...