orgertot
orgertot

Reputation: 197

Rails: How to create through a long :through relation

I want to create a result_unit like this Member.first.workouts.first.workout_sets.first.result_unit.create({"name"=>"test"}) but I also want to have the possibility to use Member.first.result_unit.create({"name"=>"test"}).

This is my Setup:

Member.rb

has_many :workouts
has_many :workout_sets, through: :workouts
has_many :result_units, through: :workout_sets

Workout.rb

belongs_to :member
has_many :workout_sets

WorkoutSet.rb

belongs_to :workout
has_one :result_unit
accepts_nested_attributes_for :result_unit

ResultUnit.rb

belongs_to :member
belongs_to :workout_set

Create in WorkoutSet-Controller

def create
        @workout = current_user.workouts.find(params[:workout_id])
        @workout_set = @workout.workout_sets.create(workout_set_params)
        @result_unit = @workout.find(@workout_set).result_unit.create(result_unit_params)
        redirect_to workout_path(@workout)
    end

I get the error undefined method create for nil:NilClass for the create of the ResultUnit.

Upvotes: 0

Views: 28

Answers (2)

wspurgin
wspurgin

Reputation: 2733

The best approach here is assigning the ResultUnit to the WorkoutSet. Since that WorkoutSet is associated with the workout, it'll have the result_unit.

@result_unit = @workout_set.result_unit = ResultUnit.create(result_unit_params)

Upvotes: 2

Lanny Bose
Lanny Bose

Reputation: 1857

Once you've defined @workout_set, you don't need to re-find it again. It's already in memory.

@result_unit = @workout_set.create_result_unit(result_unit_params)

Note the change in syntax. Take a look at the Rails API documentation for associations. For one-to-one relationships (belongs_to and has_one) the method is create_other() instead of others.create().

Upvotes: 2

Related Questions