Rails: find_or_create 关系
Rails: find_or_create relation
如果我为锻炼创建新练习,我的字段 member_id
是空的。
workout.rb
belongs_to :member
has_and_belongs_to_many :exercises
def add_exercise_with_name(exercise_name)
self.exercises << Exercise.find_or_create_by(name: exercise_name)
end
exercise.erb
has_and_belongs_to_many :workouts
belongs_to :member
exercise_controller.erb
def create
@workout = current_user.workouts.find(params[:workout_id])
@exercise = @workout.add_exercise_with_name(exercises_params['name'])
redirect_to workout_path(@workout)
end
如何为练习添加成员?
在您的 Workout
型号上试试这个:
def add_exercise_with_name(exercise_name, member)
self.exercises << Exercise.find_or_create_by(name: exercise_name, member: member)
end
然后在你的控制器中传入成员:
member = Member.find_by whatever_column: 'value'
@exercise = @workout.add_exercise_with_name(exercises_params['name'], member)
将 id 作为额外参数传递给该方法。
def add_exercise_with_name(exercise_name, member_id)
self.exercises << Exercise.find_or_create_by(name: exercise_name, member_id: member_id)
end
这有副作用。现在 find_or_create
调用将在查找练习时考虑 member_id
。如果这是不可取的,请使用 create_with(member_id: member_id)
.
self.exercises << Exercise.create_with(member_id: member_id).find_or_create_by(name: exercise_name)
此外,您可以使用块语法:
self.exercises << Exercise.find_or_create_by(name: exercise_name) do |exercise|
exercise.member_id = member_id
end
如果您遵循关联,则外键会自动填充。
在控制器中,您还可以通过关联使用 ActiveRecord 请求:
class Member < ActiveRecord::Base
has_many :workouts
has_many :exercises, through: :workouts
end
class Workout < ActiveRecord::Base
belongs_to :member
has_and_belongs_to_many :exercises
end
class Exercise < ActiveRecord::Base
belongs_to :member
has_and_belongs_to_many :workouts
end
class ExercisesController < ActionController::Base
before_action :get_workout
def create
@workout.exercises.where(name: exercises_params['name']).first_or_create
redirect_to workout_path(@workout)
end
private
def get_workout
@workout = current_user.workouts.find(params[:workout_id])
end
end
如果我为锻炼创建新练习,我的字段 member_id
是空的。
workout.rb
belongs_to :member
has_and_belongs_to_many :exercises
def add_exercise_with_name(exercise_name)
self.exercises << Exercise.find_or_create_by(name: exercise_name)
end
exercise.erb
has_and_belongs_to_many :workouts
belongs_to :member
exercise_controller.erb
def create
@workout = current_user.workouts.find(params[:workout_id])
@exercise = @workout.add_exercise_with_name(exercises_params['name'])
redirect_to workout_path(@workout)
end
如何为练习添加成员?
在您的 Workout
型号上试试这个:
def add_exercise_with_name(exercise_name, member)
self.exercises << Exercise.find_or_create_by(name: exercise_name, member: member)
end
然后在你的控制器中传入成员:
member = Member.find_by whatever_column: 'value'
@exercise = @workout.add_exercise_with_name(exercises_params['name'], member)
将 id 作为额外参数传递给该方法。
def add_exercise_with_name(exercise_name, member_id)
self.exercises << Exercise.find_or_create_by(name: exercise_name, member_id: member_id)
end
这有副作用。现在 find_or_create
调用将在查找练习时考虑 member_id
。如果这是不可取的,请使用 create_with(member_id: member_id)
.
self.exercises << Exercise.create_with(member_id: member_id).find_or_create_by(name: exercise_name)
此外,您可以使用块语法:
self.exercises << Exercise.find_or_create_by(name: exercise_name) do |exercise|
exercise.member_id = member_id
end
如果您遵循关联,则外键会自动填充。 在控制器中,您还可以通过关联使用 ActiveRecord 请求:
class Member < ActiveRecord::Base
has_many :workouts
has_many :exercises, through: :workouts
end
class Workout < ActiveRecord::Base
belongs_to :member
has_and_belongs_to_many :exercises
end
class Exercise < ActiveRecord::Base
belongs_to :member
has_and_belongs_to_many :workouts
end
class ExercisesController < ActionController::Base
before_action :get_workout
def create
@workout.exercises.where(name: exercises_params['name']).first_or_create
redirect_to workout_path(@workout)
end
private
def get_workout
@workout = current_user.workouts.find(params[:workout_id])
end
end