Destroy方法调用不正确

时间:2014-07-13 05:30:02

标签: ruby-on-rails ruby-on-rails-4.1

Rails 4.1
Ruby 2.0.0

在我的views / users / index.html.erb中,我有以下内容:

  <% @users.each do |u| %>
    <tr>
      <td><%= u.first %></td>
      <td><%= u.last %></td>
      <%= render partial: "layouts/show_edit_del_buttons", locals: {my_model: u} %>
    </tr>
  <% end %>

我的观点/布局/ _show_edit_del_buttons.html.erb,我有以下内容:

    <td>
      <%= link_to my_model, class: 'btn btn-info', title: 'View', 'data-toggle' => 'tooltip', 'data-placement' => 'right' do %>
        <span class="glyphicon glyphicon-search"></span>
      <% end %>
    <td>
      <%= link_to [:edit, my_model], class: 'btn btn-warning', title: 'Edit', 'data-toggle' => 'tooltip', 'data-placement' => 'right' do %>
        <span class="glyphicon glyphicon-pencil"></span>
      <% end %>
    </td>
    <td>
      <%= link_to my_model, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', title: 'Delete', 'data-toggle' => 'tooltip', 'data-placement' => 'right'  do %>
        <span class="glyphicon glyphicon-remove"></span>
      <% end %>
    </td>     

在我的controllers / users_controller.rb中,我有以下内容:

  def destroy
    @user.destroy
    respond_to do |format|
      format.html { redirect_to users_url }
      format.json { head :no_content }
    end
  end   

正确显示用户索引。当我选择“编辑”或“查看”按钮时,它的行为正常。当我选择删除按钮时,我会看到弹出窗口:您确定,当我单击确定时,我收到以下错误消息:

undefined method `destroy' for nil:NilClass

并指向控制器中的以下行:

@user.destroy

在用户控制器中定义的Index操作中调用views / layouts / _show_edit_del_buttons.html.erb partial:

def index
  @users = User.all
end

有什么想法吗?

附加说明:

我按如下方式修改了部分:

<%= render partial: "layouts/show_edit_del_buttons", locals: {my_model: u, my_id: u.id} %>

和控制器如下:

def destroy(id)
  @user = User.where(:id => id)[0] if id
  @user.destroy

现在,看起来params正确传递了。但我仍然收到错误:

ArgumentError at /users/19
wrong number of arguments (0 for 1)
Request parameters  
 {"_method"=>"delete", "authenticity_token"=>"tjNjgGzaH3Rxez1sYhn/NyZQMUqg8vUDhcmxoZI0KBs=", "action"=>"destroy", "controller"=>"users", "id"=>"19"}

当我尝试(从控制台)尝试以下内容时:

@user = User.where(:id => id)[0]

然后:

@user.destroy

记录确实被破坏了

解决方案:

在我的routes.rb中,我有:

resources :users, only: [:show, :edit, :update, :index]

我把它改为:

resources :users, only: [:show, :edit, :update, :index, :destroy]

有效

1 个答案:

答案 0 :(得分:0)

<强>控制器

首先,在控制器的destroy方法中,您没有对@user对象的任何引用:

#app/controllers/users_controller.rb
Class UsersController < ApplicationController
    def destroy
       @user.destroy # -> where is @user set?
    end
end

-

需要先定义@user变量,然后才能在其上调用.destroy。通常,你会这样做:

def destroy
   @user = User.find params[:id]
   @user.destroy
end

在Rails的更高版本中,他们实际上使用一种方法来设置带有@model钩子的before_action变量:

#app/controllers/users_controller.rb
Class UsersController < ApplicationController
    before_action :set_user, except: [:create, :index]

    private

    def set_user
        @user = User.find params[:id]
    end
end

<强>修正

要解决问题,您最好自己观察错误:

  

未定义的方法`destroy'为nil:NilClass

这是标准问题 - 基本上意味着您没有声明要调用.destroy方法的变量。

如上所述,您最好使用一种方法在控制器中设置此功能,以便在相关操作中调用@user