What objects should be passed to a link_to with tr

2019-06-11 01:11发布

问题:

What objects should I pass to my link_to for a triple nested route? I want to retrieve the exercise show page.

show.html.erb - workouts

<%= link_to exercise.name, plan_workout_exercise_path(???) %>

routes.rb

resources :plans do
 resources :workouts do
   resources :exercises
 end
end

workouts_controller.html.erb

def show
    @workout = Workout.find(params[:id])  
end

I have attempted the following, but it doesn't feed the right ID to the right model.

<%= link_to exercise.name, plan_workout_exercise_path(@plan, @workout, @exercise) %>

回答1:

You also have to get @plan in the show action:

In your workout_controller.rb:

def show
    @plan = Plan.find(params[:plan_id])
    @workout = Workout.find(params[:id])
end

In your exercise_controller.rb:

def show
    @plan = Plan.find(params[:plan_id])
    @workout = Workout.find(params[:workout_id])
    @exercise = Exercise.find(params[:id])
end

Also you can do it like this:

<%= link_to exercise.name, [@plan, @workout, exercise] %>

Recommendation: Try to get RailsForZombies 2 slides, it has a nice section how to deal with nested routes, or just look at the guides.

Also, just for the sake of having cleaner code, get the @plan in the workout_controller.rb and @plan and @workout in the exercise_controller.rb with a callback function before_filter:

class WorkoutsController < ApplicationController

    before_filter :get_plan

    def get_plan
        @plan = Plan.find(params[:plan_id])
    end

    def show
        @workout = Workout.find(params[:id])
    end

end

And like Thomas said, try avoiding those deeply nested routes.



回答2:

if you are using exercise.name I am assuming you are through a loop like @workout.exercises.each do |exercise|, right?

However, you must define the @plan in your controller.

def show
  @plan = Plan.find(params[:plan_id])
  @workout = @plan.workouts.find(params[:workout_id])
end

Then,

<%= link_to exercise.name, plan_workout_exercise_path(@plan, @workout, exercise)


回答3:

One possibility to avoid tripple nesting is structuring your routes like this:

resources :plans do
  resources :workouts, except: [:index, :show]
end

resources :workouts, only: [:index, :show] do
  resources :exercises
end

You always get by then with just one level of nesting and much easier link helpers.

<%= link_to 'Create a new workout', new_plan_workout_path(@plan) %>
<%= link_to workout.name, workout_path(@workout) %>

<%= link_to 'Create a new exercise', new_workout_exercise_path(@workout) %>
<%= link_to exercise.name, workout_exercise_path(@workout, @exercise) %>