0

I have just installed Pundit on my app. I have managed to implement pundit for the new create and show methods however when it comes to my destroy and up vote methods I get the following error Pundit::NotDefinedError in HairstylesController#upvote unable to find policy `NilClassPolicy` for `nil

here is my repo for ease of understanding if needed: https://github.com/Angela-Inniss/hair-do

I have authorized the two methods, 'upvote' and 'destroy' in my controller. I have updated the relevant policy. Please see code below.

Controller with methods in question:

  def destroy
    authorize @hairstyle
    @hairstyle = Hairstyle.find(params[:id])
    @hairstyle.destroy
    redirect_to hairstyles_path
  end

  def upvote
    authorize @hairstyle
    @hairstyle = Hairstyle.find(params[:id])
    @hairstyle.upvote_from current_user
    redirect_to hairstyles_path
  end

pundit policy.rb file:


  def upvote?
    record.user == user
    # - record: the restaurant passed to the `authorize` method in controller
    # - user:   the `current_user` signed in with Devise.
  end

  def destroy?
    record.user == user
  end

index.html.erb file destroy html

 <% if policy(hairstyle).destroy? %>
              <p><%= link_to "Delete", hairstyle_path(hairstyle),method: :delete, data: { confirm: "Are you sure?" }%></p>
           <% end %>

index.html.erb file upvote html (which worked before i added pundit )

   <%= link_to like_hairstyle_path(hairstyle), method: :put do %>
               <i class="fa fa-heart">
                <span><%= hairstyle.get_upvotes.size %><span>
               </i>
            <% end %>

I would like the user to be able to upvote on a hairstyle I would like the user to be able to delete their hairstlye.

Angela Inniss
  • 359
  • 1
  • 2
  • 18

2 Answers2

2

Shouldn't you call authorize after that the object is set? Try to move from

authorize @hairstyle
@hairstyle = Hairstyle.find(params[:id])

to

@hairstyle = Hairstyle.find(params[:id])
authorize @hairstyle
Ursus
  • 29,643
  • 3
  • 33
  • 50
  • 2
    I was just about to say that. The hairstyle is nil, and it uses the class of the thing you’re trying to authorize, for the policy class (HairstylePolicy, NilClassPolicy). – Nate Apr 28 '19 at 13:15
  • I tried what you said for the delete method and it worked however for the upvote method I changed authorization to AFTER the object was set then clicked the upvote on my site I get this error ``Pundit::NotAuthorizedError in HairstylesController#upvote not allowed to upvote? this... #<`` It's strange because as you can see I have authorized the method :S Any thoughts? – Angela Inniss Apr 28 '19 at 20:09
0

Hello I resolved my issue. Part of the reason was, as you both said above that I was calling the authorize in the wrong place it should have been after the object was set.

Next the reason why I got the error:

Pundit::NotAuthorizedError in HairstylesController#upvote not allowed to upvote? this... #< was because instead of putting:

def upvote? record.user == user end

in my policy for the upvote? method,

I should have put this:

def upvote? return true end

Angela Inniss
  • 359
  • 1
  • 2
  • 18