0

I'm following along with the rails tutorial by Michael Hartl Chapter 13 but instead of microposts, I'm creating animals.

My view of animals shows a "delete" hyperlink that is supposed to delete an animal record from my list but the view action doesn't seem to get to the point where it uses the destroy method at all.
I read through all the answers in a similar post here but did not find those answers to help in my case.

I'm currently in a development environment on AWS cloud9 as instructed in the tutorial. I really appreciate any pointers as I have been struggling with this one for days.

Here is my code from the view:

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

This view is called from a feed view:

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

Which comes from the home page view:

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

I have reviewed the <%= link_to... line many times and it seems to be correct. My controller code is:

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

I noticed that I never see the flash "Animal deleted" so that tells me I probably don't get to that point in the controller method.

My model code is:

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

Here is my application.js file from app/assets/javascripts:

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

Here is what the server log says after I click on the "delete" tag in my rendered view in the browser:

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)

I also found one of my tests to fail:

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>'
JasonArg123
  • 188
  • 1
  • 1
  • 14
  • could you please change `@animal.destroy` to `@animal.destroy!` and show the results? – Igor Drozdov Sep 06 '18 at 23:03
  • 1
    I don't think the request is going there, as there is a `filter chain halted`. What's with `correct_user` ? Why do you have `before_action :correct_user, only: :destroy` ? Can you update your question with that method ? – Kedarnag Mukanahallipatna Sep 07 '18 at 02:31
  • @IgorDrozdov, adding "!" produced exactly the same result. – JasonArg123 Sep 07 '18 at 03:29
  • @KedarnagMukanahallipatna, I've updated my controller code to include it. – JasonArg123 Sep 07 '18 at 03:35
  • 1
    Can you put a debugger in `correct_user` and see what is being returned ? I think `@animal` is `nil`. Can you also share your `routes` for `delete` – Kedarnag Mukanahallipatna Sep 07 '18 at 03:45
  • 1
    Another thing, you're already passing `animal` in the `link_to`, why do you even want to get @animal from `correct_user` ? I think you want to delete the `animal`, you're sending it in link ? Remove, before_filter and in your controller `action`, put a `debugger` and check params. If you're getting `id`, then you can do `@animal = Animal.find(params[:id])` and then `@animal.destory`. – Kedarnag Mukanahallipatna Sep 07 '18 at 03:56
  • Thank you for the debugger suggestion, @KedarnagMukanahallipatna. I learned about "byebug" and started using it. Good to know! – JasonArg123 Sep 07 '18 at 16:42

1 Answers1

6

Filter chain halted as :correct_user rendered or redirected

The problem is you have @animals(which is not defined) instead of @animal, so redirect_to root_url if @animals.nil? always succeeds which results in destroy action failing always. You should change @animals to @animal

def correct_user
  @animal = current_user.animals.find_by(id: params[:id])
  redirect_to root_url if @animal.nil?
end
Pavan
  • 33,316
  • 7
  • 50
  • 76