未定义方法“destroy”用于空值:NilClass

11

我的应用程序成功地每次用户提交一些统计数据时为表创建行。现在我想提供一个删除按钮来删除某些行。

当我点击删除按钮时,我会收到以下错误:

undefined method `destroy' for nil:NilClass

看起来Rails在这种情况下不理解销毁方法,或者由于某些原因Rails没有看到要销毁的内容,因此出现了nil:NilClass。

我的第一个问题是确定哪种情况,如果有的话。

我的第二个问题是如何修复它 :D

这是我的show.html:

<% provide(:title, "Log" ) %>
<% provide(:heading, "Your Progress Log") %>

<div class="row">  
  <div class="span8">
    <% if @user.status_update.any? %>
      <h3>Status Updates (<%= @user.status_update.count %>)</h3>    
      <table>
        <thead>
          <tr>
            <th>Entry Date</th>
            <th>Weight</th>
            <th>BF %</th>
            <th>LBM</th>
            <th>Fat</th>
            <th>Weight Change</th>
            <th>BF % Change</th>
            <th>Fat Change</th>
          </tr>
        </thead>
      <tbody class = "status updates">
          <%= render @status_updates %>
      </tbody>        
    <% end %>
  </div>
</div>

"<%= render @status_updates %>" 调用了 _status_update 部分视图文件。
 <tr>
 .
 .
 .
 . 
 <% if current_user==(status_update.user) %> 
 <td>
       <%= link_to "delete", status_update, method: :delete %>

 </td>
 <%  end  %>         

</tr>                                    

最后,这里是 StatusUpdateController。

def destroy
    @status_update.destroy
    redirect_to root_url
end

以下是错误页面上的参数:

{"_method"=>"delete",
 "authenticity_token"=>"w9eYIUEd2taghvzlo7p3uw0vdOZIVsZ1zYIBxgfBymw=",
 "id"=>"106"}

1
@status_update在您的控制器中未定义。您需要通过参数(params[:id])访问它,或者如果使用资源,则使用resource.destroy。请检查您的rake routes以确保使用正确的参数。 - Damien Roche
你是否在destroy方法的before_filter中分配了@status_update?如果没有,那就是问题所在。 - Zach Kemp
1个回答

12

由于您没有展示任何可能赋值@status_update的代码(过滤器或其他),我认为不存在这样的代码。因此,您在destroy方法中的实例变量@status_update未被设置。您需要使用对象的ID查询类。

请按以下方式重写您的destroy方法:

def destroy
    @status_update = StatusUpdate.find(params[:id])
    if @status_update.present?
      @status_update.destroy
    end
    redirect_to root_url
end

注意: 将类名 StatusUpdate 替换为您实际的类名。


我明白了。我正在跟随一个不同项目的教程,其中有一些代码片段我之前不理解,现在我看到它们确切的目的了。它有一个名为“correct user”的私有函数,将@status_update实例分配给一个对象ID。感谢您的帮助。 - Nick Res
该方法是如何调用的?何时调用? - HungryCoder
在 before 过滤器中,我放置了以下代码:before_filter :correct_user, only: :destroy然后在 private 中,我有以下代码:private def correct_user @status_update = current_user.status_update.find_by_id(params[:id]) redirect_to root_url if @status_update.nil? end - Nick Res
1
尝试将:destroy放入一个数组中,例如before_filter :correct_user, :only => [:destroy] - HungryCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接