2015-10-20 22 views
2

如果我爲鍛鍊創建新練習,那麼我的字段member_id爲空。Rails:find_or_create relation

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 

我怎麼可能添加成員進行演練?

回答

3

傳遞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 
+1

由於提出了警告,因此可能會更好。 –

+0

所以如果練習belongs_to成員,我會做'find_or_create_by(name:exercise_name)'它會使用同名的練習,但可能不同的「所有者」/成員? – orgertot

+1

@orgertot是的。如果在'find_or_create_by'中包含'member_id',那麼查詢'where'子句將包含條件'where name ='foo'AND member_id = 1'。取決於你想如何設計你的系統,這可能是也可能不是你想要的。 – Mohamad

1

試試這個在您的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) 
0

如果按照關聯,則外鍵自動填充。 在控制器中,您還可以通過關聯使用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 
相關問題