0

I have a set of nested routes that look like this:

  resources :workouts do
    resources :exercises do
      resources :reports, shallow: true
    end
  end

I tried to make them as shallow as possible, but not nesting them simply generated too many errors.

Right now they're working fine except when I try to access the exercises#index page for a specific workout. I'm linking the page like this:

<%= link_to 'Add/Edit Exercises', workout_exercises_path(@workout, exercise), method: :index %>

And when I click that link I get:

ActiveRecord::RecordNotFound at /workouts/3/exercises
Couldn't find Workout without an ID

The error is called on my exercises_controller on the indicated line:

class ExercisesController < ApplicationController
  before_action :authenticate_user!

  def index
      @workout = Workout.friendly.find(params[:id]) <<<<<THIS LINE
      @exercise = Exercise.new
      @exercises = Exercise.all
  end

  def new
    @exercise = Exercise.new
  end

  def create
    @workout = Workout.friendly.find(params[:id])
    exercise = @workout.exercises.new(exercise_params)
    exercise.user = current_user

    if exercise.save
      flash[:notice] = "Results saved successfully."
      redirect_to [@workout]
    else
      flash[:alert] = "Results failed to save."
      redirect_to [@workout]
    end
  end

  def destroy
    @workout = Workout.friendly.find(params[:workout_id])
    exercise = @workout.exercises.find(params[:id])

    if exercise.destroy
      flash[:notice] = "Exercise was deleted successfully."
      redirect_to [@workout]
    else
      flash[:alert] = "Exercise couldn't be deleted. Try again."
      redirect_to [@workout]
    end
  end

  private

  def exercise_params
      params.require(:exercise).permit(:name, :needs_seconds, :needs_weight, :needs_reps, :workout_id)
  end

  def authorize_user
    exercise = Exercise.find(params[:id])
    unless current_user == current_user.admin?
      flash[:alert] = "You do not have permission to create or delete an exercise."
      redirect_to [exercise.workout]
    end
  end
end

The friendly.find is because I am using the friendly_id gem, which generates slugs instead of ids in the url. I use it in the same manner in other working models, so I do not believe this is causing the current problem.

Can anyone see why I'm getting this error? I have typed @workout into the live shell of my error and it says that @workout is nil, which means it isn't getting the value somehow. I know this is important information, but don't know how to fix it.

Liz
  • 1,369
  • 2
  • 26
  • 61

2 Answers2

0

The problem is:

  • Your route was /workouts/3/exercises, so it format like: /workouts/:workout_id/exercises

  • So just modify your create method a bit:

    def create
      @workout = Workout.friendly.find(params[:workout_id])
      exercise = @workout.exercises.build(exercise_params)
      ...
    end
    
Hieu Pham
  • 6,577
  • 2
  • 30
  • 50
  • This I think got through the original error, but now it has a problem with my params: `param is missing or the value is empty: exercise` – Liz Jun 03 '16 at 01:30
  • And will I have to modify the correlative section of my `destroy` method as well? – Liz Jun 03 '16 at 01:31
  • Add debug breakpoint inside this method `exercise_params` and see which param is missing! – Hieu Pham Jun 03 '16 at 01:32
  • I don't know how to do a debug breakpoint, but when I put @exercise into my error message's live shell it came back as `nil`. Is this what you mean? – Liz Jun 03 '16 at 01:34
  • Make sure your params has this format {exercise: {name: ..., ...}} because you require `exercise` – Hieu Pham Jun 03 '16 at 01:44
  • The current params are: `def exercise_params params.require(:exercise).permit(:name, :needs_seconds, :needs_weight, :needs_reps, :workout_id) end` – Liz Jun 03 '16 at 01:49
  • Yes I see, what is the param values before running `exercise_params`, it may miss what you expected – Hieu Pham Jun 03 '16 at 02:09
  • Sorry. How do I find that out? – Liz Jun 03 '16 at 02:11
0
  def index
      @workout = Workout.friendly.find(params[:workout_id])
      @exercise = Exercise.new
      @exercises = Exercise.all
  end

Try this one, Hope this would help you.

Atchyut Nagabhairava
  • 1,295
  • 3
  • 16
  • 23
  • Unfortunately, even with this change I still get `param is missing or the value is empty: exercise` called on the params of my `exercise_controller`. – Liz Jun 03 '16 at 14:04