【问题标题】:link_to 'delete' is not destroying a recordlink_to 'delete' 不会破坏记录
【发布时间】:2018-09-06 21:33:41
【问题描述】:

我正在关注 Michael Hartl Chapter 13 的 Rails 教程,但我正在创建动物而不是微博。

我的动物视图显示了一个“删除”超链接,它应该从我的列表中删除一条动物记录,但视图操作似乎根本没有达到它使用销毁方法的地步。
我阅读了类似帖子 here 中的所有答案,但没有找到对我的情况有帮助的答案。

按照教程中的说明,我目前在 AWS cloud9 上的开发环境中。我真的很感激任何指点,因为我已经为此苦苦挣扎了好几天。

这是我的代码:

<li id="animal-<%= animal.id %>">
  <%= link_to gravatar_for(animal.user, size: 50), animal.user %>
  <span class="user"><%= link_to animal.user.name, animal.user %></span>
  <span class="ear_tag"><%= animal.ear_tag %></span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(animal.created_at) %> ago.
    <% if current_user?(animal.user) %>
      <%= link_to "delete", animal, method: :delete, data: { confirm: "You sure?" } %>
    <% end %>
  </span>
</li>

这个视图是从一个提要视图中调用的:

<% if @feed_items.any? %>
  <ol class="animals">
    <%= render @feed_items %>
  </ol>
  <%= will_paginate @feed_items %>
<% end %>

来自主页视图:

<div class="col-md-8">
  <h3>Animal Feed</h3>
  <%= render 'shared/feed' %>
</div>

我已经多次查看&lt;%= link_to... 行,它似乎是正确的。我的控制器代码是:

class AnimalsController < ApplicationController
  before_action :logged_in_user,  only: [:create, :destroy]
  before_action :correct_user,    only: :destroy

  def destroy
    @animal.destroy
    flash[:success] = "Animal deleted"
    redirect_to request.referrer || root_url
  end

  def correct_user
    @animal = current_user.animals.find_by(id: params[:id])
    redirect_to root_url if @animals.nil?
  end
end

我注意到我从来没有看到过“动物已删除”的 Flash,所以这告诉我我可能在控制器方法中没有达到这一点。

我的型号代码是:

class Animal < ApplicationRecord
  belongs_to :user
  default_scope -> {order(created_at: :desc) }
  validates :user_id, presence: true
  validates :ear_tag, presence: true, length: {maximum: 20}
end

这是我的 app/assets/javascripts 中的 application.js 文件:

//= require jquery
//= require bootstrap
//= require rails-ujs
//= require turbolinks
//= require_tree

这是我在浏览器中单击渲染视图中的“删除”标签后服务器日志显示的内容:

Started DELETE "/animals/308" for 23.25.133.17 at 2018-09-06 21:11:06 +0000
Processing by AnimalsController#destroy as HTML
  Parameters: {"authenticity_token"=>"vwF6cWow+6B3BxOiJElVY0aQmMGr4WLWDOCxgB0C03nRLcQDKC3YCUqBr4ahVwlSKN7bEYRrmGytyI1fPgvavw==", "id"=>"308"}
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 102], ["LIMIT", 1]]
  Animal Load (0.2ms)  SELECT  "animals".* FROM "animals" WHERE "animals"."user_id" = ? AND "animals"."id" = ? ORDER BY "animals"."created_at" DESC LIMIT ?  [["user_id", 102], ["id", 308], ["LIMIT", 1]]
Redirected to https://cabfa13dd4f34e67b634d4f52a7a046f.vfs.cloud9.us-west-2.amazonaws.com/
Filter chain halted as :correct_user rendered or redirected
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)

我还发现我的一项测试失败了:

FAIL["test_animal_interface", AnimalsInterfaceTest, 1.5248641059999954]
 test_animal_interface#AnimalsInterfaceTest (1.53s)
        "Animal.count" didn't change by -1.
        Expected: 38
          Actual: 39
        test/integration/animals_interface_test.rb:33:in `block in <class:AnimalsInterfaceTest>'

【问题讨论】:

  • 能否请将@animal.destroy 更改为@animal.destroy! 并显示结果?
  • 我不认为请求会去那里,因为有一个filter chain haltedcorrect_user 是怎么回事?为什么你有 before_action :correct_user, only: :destroy ?你能用那种方法更新你的问题吗?
  • @IgorDrozdov,添加“!”产生了完全相同的结果。
  • 你能在correct_user 中放一个调试器,看看返回了什么?我认为@animalnil。你也可以分享你的routesdelete
  • 另外一件事,你已经在link_to 中传递了animal,为什么还要从correct_user 获取@animal?我想你想删除animal,你在链接中发送它?删除 before_filter 并在您的控制器 action 中,放入 debugger 并检查参数。如果你得到id,那么你可以先@animal = Animal.find(params[:id]),然后@animal.destory

标签: ruby-on-rails ruby-on-rails-5


【解决方案1】:

过滤器链因 :correct_user 呈现或重定向而停止

问题是你有@animals这是未定义)而不是@animal,所以redirect_to root_url if @animals.nil? 总是成功这导致破坏动作总是失败。您应该将@animals 更改为@animal

def correct_user
  @animal = current_user.animals.find_by(id: params[:id])
  redirect_to root_url if @animal.nil?
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    相关资源
    最近更新 更多