Rails 4 活动记录错误:找不到删除具有嵌套路由的对象时的记录



我的应用程序中有以下结构:

resources :workouts do
  resources :exercises
end

锻炼has_many练习。我显示它,以便在workouts#show页面上有一个指向exercises#index页面的链接,用于添加/编辑属于该锻炼的练习。在exercises#index页面上,练习列表正确填充,但是当我尝试删除练习时,它给我这个错误:Couldn't find Exercise with 'id'=10 [WHERE "exercises"."workout_id" = ?]

我的exercises#index页面是:

<div class="container col-sm-10 col-sm-push-1" style="margin-top: 100px">
  <div class="opaque-card md-well well">
    <h1>Current Exercises:</h1>
      <% @exercises.each do |exercise| %>
        <p><%= exercise.name %> (<%= link_to "Delete #{exercise.name}", workout_exercise_path(@workout, exercise), method: :delete, data: { confirm: 'Are you sure?' } %>)</p>
      <% end %>
    <h1>Add New Exercises:</h1>
      <%= render 'exercises/form' %>
  </div> <!-- opaque card -->
</div> <!-- container -->

我的相应routes是:

       workout_exercises GET    /workouts/:workout_id/exercises(.:format)          exercises#index
                         POST   /workouts/:workout_id/exercises(.:format)          exercises#create
    new_workout_exercise GET    /workouts/:workout_id/exercises/new(.:format)      exercises#new
   edit_workout_exercise GET    /workouts/:workout_id/exercises/:id/edit(.:format) exercises#edit
        workout_exercise GET    /workouts/:workout_id/exercises/:id(.:format)      exercises#show
                         PATCH  /workouts/:workout_id/exercises/:id(.:format)      exercises#update
                         PUT    /workouts/:workout_id/exercises/:id(.:format)      exercises#update
                         DELETE /workouts/:workout_id/exercises/:id(.:format)      exercises#destroy
                workouts GET    /workouts(.:format)                                workouts#index
                         POST   /workouts(.:format)                                workouts#create
             new_workout GET    /workouts/new(.:format)                            workouts#new
            edit_workout GET    /workouts/:id/edit(.:format)                       workouts#edit
                 workout GET    /workouts/:id(.:format)                            workouts#show
                         PATCH  /workouts/:id(.:format)                            workouts#update
                         PUT    /workouts/:id(.:format)                            workouts#update
                         DELETE /workouts/:id(.:format)                            workouts#destroy

这是我的exercises_controller.rb

class ExercisesController < ApplicationController
  before_action :authenticate_user!
  def index
      @workout = Workout.friendly.find(params[:workout_id])
      @exercise = Exercise.new
      @exercises = Exercise.all
  end
  def new
    @workout = Workout.friendly.find(params[:id])
    @exercise = Exercise.new
  end
  def create
  #  require 'pry' ; binding.pry
    @workout = Workout.friendly.find(params[:workout_id])
    exercise = @workout.exercises.build(exercise_params)
    exercise.user = current_user
    if exercise.save
      flash[:notice] = "Exercise created successfully."
      redirect_to [@workout]
    else
      flash[:alert] = "The exercise failed to save."
      redirect_to [@workout]
    end
  end
  def edit
    @workout = Workout.friendly.find(params[:id])
    exercise = Exercise.find(params[:id])
    exercise.user = current_user
  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

我已经尝试取消嵌套路由,这会导致的错误远远多于解决的错误。任何人都可以看到为什么我收到此错误或如何解决它?

补充:以下是错误之前我的服务器日志中的params

Started DELETE "/workouts/d/exercises/10" for ::1 at 2016-06-05 10:39:29 -0700
Processing by ExercisesController#destroy as HTML
  Parameters: {"authenticity_token"=>"xAWbVPHRNJeGSWhThaAMDf/FUYXav4WXrMBnjoX7s3g+gTQEVo0r9wIhSxIB+yH8sdwhcxfDZV9SinaLSUEiMA==", "workout_id"=>"d", "id"=>"10"}
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]
  Workout Load (0.1ms)  SELECT  "workouts".* FROM "workouts" WHERE "workouts"."slug" = ?  ORDER BY "workouts"."id" ASC LIMIT 1  [["slug", "d"]]
  Exercise Load (0.2ms)  SELECT  "exercises".* FROM "exercises" WHERE "exercises"."workout_id" = ? AND "exercises"."id" = ? LIMIT 1  [["workout_id", 4], ["id", 10]]
Completed 404 Not Found in 6ms (ActiveRecord: 0.4ms)
ActiveRecord::RecordNotFound - Couldn't find Exercise with 'id'=10 [WHERE "exercises"."workout_id" = ?]:

增加:exercises#index中引用的表格:

<div class="row">
  <div class="col-xs-10 col-xs-push-1">
    <%= form_for [@workout, @exercise] do |f| %>
      <%= f.hidden_field :workout_id, value: @workout.id %>
      <div class="form-group">
        <%= f.label :name, class: 'sr-only' %>
        <%= f.text_field :name, class: 'form-control', placeholder: "Enter exercise name" %>
      </div>
      <div class="form-group col-xs-4">
        <p><%= f.label :needs_seconds, class: 'sr-only' %>
        <%= f.check_box :needs_seconds, class: 'check_box' %> Report seconds?</p>
      </div>
      <div class="form-group col-xs-4">
        <p><%= f.label :needs_reps, class: 'sr-only' %>
        <%= f.check_box :needs_reps, class: 'check_box' %> Report reps?</p>
      </div>
      <div class="form-group col-xs-4">
        <p><%= f.label :needs_weight, class: 'sr-only' %>
        <%= f.check_box :needs_weight, class: 'check_box' %> Report weight?</p>
      </div>
      <div class="text-center"><%= f.submit "Create Exercise", class: 'btn btn-primary' %></div>
    <% end %>
  </div>
</div>
我认为

问题是Workout.friendly.find(params[:workout_id])找不到任何记录。你能确保它确实找到一些东西吗,通过将其打印到rails控制台,

@workout = Workout.friendly.find(params[:workout_id])
exercise = @workout.exercises.find(params[:id])
p "Workout: ", @workout
p "Exercise: ", exercise #they should print the found object or nil in your rails server console

如果您看到nil我会说通过友好ID查找会导致问题。

更新:

我的坏。我没见过。因此,当您构建锻炼时,请查看您正在传递exercise_params,如果您注意到exercise_params还有一个必须传递nil workout_id,因此它会重写新创建的exercise中的workout_id值。只需从exercise参数中删除workout_id即可。并尝试再创建一些锻炼并再次测试这些。

活动记录:

:记录未找到 - 找不到"id"=10 的锻炼 [其中"练习"。workout_id" = ?

代码中有两个问题。首先,@exercises变量保存所有练习记录,而不是@workout的练习。其次,使用 exercise 变量,您尝试使用params[:id]找到锻炼的锻炼,这实际上是视图中循环@exercises之一的id。因此,Rails 无法找到包含组合 (:workout_id & :id) 的记录,因此错误也是如此。

溶液

destroy方法中将exercise = @workout.exercises.find(params[:id])更改为exercise = Exercise.find(params[:id])

def destroy
  @workout = Workout.friendly.find(params[:workout_id])
  exercise = Exercise.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

最新更新