Search code examples
ruby-on-railspundit

Pundit - authorize not being called, but no error is being thrown


I'm using pundit for authorization. It's not working as expected, but when calling authorize no error is being thrown to say no method.

spec:

it "should let a user destroy their own picture" do
  sign_in(user2)
  expect do
    delete :destroy, { id: p1.id }
    expect(response.status).to eq(200)
  end.to change { Picture.count }.by(-1)
end

it "should not let a user delete another user's picture" do
  sign_in(user2)
  expect do
    delete :destroy, { id: p1.id }
    expect(response.status).to eq(403)
  end.to change { Picture.count }.by(0)
end

ApplicationController:

class ApplicationController < ActionController::Base
  ...
  include Pundit
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
  ...
end

PicturesController:

class PicturesController < ApplicationController
  def destroy
    @picture = Picture.find_by_id(params[:id])
    authorize(@picture)
    @picture.destroy
    redirect_to pictures_path
  end
end

ApplicationPolicy

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end

  def scope
    Pundit.policy_scope!(user, record.class)
  end

  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user = user
      @scope = scope
    end

    def resolve
      scope
    end
  end
end

PicturePolicy

class PicturePolicy < ApplicationPolicy
  def destroy?
    @user&.id == @record&.user_id
  end
end

When I run my test with the authorize(picture) line, neither get destroyed, without it, both get destroyed. When adding some put statements inside of PicturePolicy#destroy?, they don't get shown. If I add a ApplicationPolicy#destroy?, it also doesn't seem to be called. However when I add authorize(obj) to my controller, nothing after that code is being run, neither policy#authorize is being run, but a 200 is being returned.

Any idea what I'm missing here?


Solution

  • Found the issue. I was using a safe access &. in a version of ruby it doesn't exist in. Removing that fixed it.