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

时间:2016-06-05 17:47:46

标签: ruby-on-rails activerecord

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

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

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

ADDED:以下是来自错误之前的服务器日志的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" = ?]:

ADDED: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>

2 个答案:

答案 0 :(得分:0)

我认为问题是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也有一个workout_id必须通过nil,那么它会重写{{1}的值在新创建的workout_id中。从你的exercise参数中删除workout_id。并尝试再创建一些exersize并再次测试。

答案 1 :(得分:0)

  

ActiveRecord :: RecordNotFound - 无法找到练习&#39; id&#39; = 10   [在哪里&#34;练习&#34;。&#34; workout_id&#34; =?]

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

<强> 解决方案

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

destroy