Search code examples
ruby-on-rails-4pundit

Rails 4 - Pundit::PolicyScopingNotPerformedError


I am new with Pundit ( I am used to Cancan...) and I am training on it, trying to follow the ReadMe.. but I am stuck with the PolicyScoping error when indexing all sheets from my Sheet model

#application_controller.rb
class ApplicationController < ActionController::Base
    include Pu ndit 
    .../... 
end  

#sheets_controller.rb
class SheetsController < ApplicationController
    after_filter :verify_authorized, :except => :index, unless: :devise_controller?
    after_filter :verify_policy_scoped, :only => :index

    before_action :set_sheet, only: [:show, :edit, :update, :destroy]
    respond_to :html, :json

    def index 
      @sheets = SheetPolicy::Scope.new(current_user, Sheet).resolve
      build_json_header_list
      respond_to do |format|
        format.html
        format.json { 
          build_json_data_list
          render json: @data 
        }
      end
    end
    .../... 
end

#sheet_policy.rb
class SheetPolicy < ApplicationPolicy
  .../... 
  class Scope < Scope
    def resolve
      byebug
      if user.system_admin?
        scope.all
      else
        scope.where(:user_id => user.id)
      end
    end
  end
end

The index methods ais correctly executed , the sheet_policy scope is correctly resolved ( debugged in console ... and the view start rendering ... so I guess the error comes from the after_filer in the sheets_controller

    after_filter :verify_policy_scoped, :only => :index

BUT I thought ( I must e wrong...) that resolving the scope wit the sheet policy SHOUDL have authorised the index action ?the Pundit doc is not very clear on it ...

here is the console log

=====================
# development.log
Started GET "/sheets" for ::1 at 2015-09-18 11:59:30 +0200
Processing by SheetsController#index as HTML
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]

[18, 27] in .../app/policies/sheet_policy.rb
(byebug) user.system_admin?
  Role Load (22.9ms)  SELECT "roles".* FROM "roles"
true
(byebug) c
  CACHE (0.3ms)  SELECT "roles".* FROM "roles"
  Rendered sheets/index.html.erb within layouts/administration (17.0ms)
  .../...
  Rendered layouts/administration/_scripts.html.erb (286.9ms)
  Completed 500 Internal Server Error in 29650ms (Views: 6149.5ms | ActiveRecord: 25.3ms)
------

  Pundit::PolicyScopingNotPerformedError - Pundit::PolicyScopingNotPerformedError:
    pundit (1.0.1) lib/pundit.rb:107:in `verify_policy_scoped'  activesupport (4.2.3)  
    lib/active_support/callbacks.rb:430:in `block in make_lambda'
    .../...
    activesupport (4.2.3) lib/active_support/callbacks.rb:88:in `run_callbacks'
    actionpack (4.2.3) lib/abstract_controller/callbacks.rb:19:in `process_action'
    .../...
    activesupport (4.2.3) lib/active_support/notifications.rb:164:in `block in instrument'
    .../...
    actionpack (4.2.3) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
    .../...
    activerecord (4.2.3) lib/active_record/railties/controller_runtime.rb:18:in `process_action'

Solution

  • You shouldn't be calling your SheetPolicy::Scope.resolve method directly - use Pundit's helper methods.

    In this case, you can simply call @sheets = policy_scope(Sheet) instead, which is also what Pundit is checking for.