2015-09-14 4 views
2

Я довольно новичок в использовании этого драгоценного камня Pundit, но, похоже, у вас проблемы с пониманием системы политик. Из всего, что я прочитал все это, кажется, правильно, хотя я все еще получаю ошибкуPundit :: PolicyScopingNotPerformedError

Контроллер Применение

class ApplicationController < ActionController::Base 
    include Pundit 
    protect_from_forgery 
    before_filter :authenticate_person! 

    # Verify that controller actions are authorized. Optional, but good. 
    after_filter :verify_authorized, except: :index 
    after_filter :verify_policy_scoped, only: :index 


    rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized 

    private 

    def pundit_user 
    Person.find_by_id(current_person) 
    end 

    def user_not_authorized 
    flash[:alert] = "You are not authorized to perform this action." 
    # redirect_to(request.referrer || root_path) 
    end 
end 

политики Применение

class ApplicationPolicy 
    attr_reader :user, :record 

    def initialize(user, record) 
    raise Pundit::NotAuthorizedError, "must be logged in" unless user 
    @user = user 
    @record = record 
    end 

    def index? 
    false 
    end 

    def show? 
    scope.where(:id => record.id).exists? 
    end 

    def create? 
    false 
    end 

    def new? 
    create? 
    end 

    def update? 
    false 
    end 

    def edit? 
    update? 
    end 

    def destroy? 
    false 
    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 

Сообщение об ошибке

Pundit::AuthorizationNotPerformedError in Devise::SessionsController#new 

ответ

2

Вы вероятно, нужно проверить this section из Readme Pundit's.

В основном говорится, что при использовании verify_authorized используется в after_action, он проверяет, действительно ли был вызван authorized.

Pundit добавляет к вашим контроллерам метод, называемый verify_authorized. Этот метод вызовет исключение, если authorize еще не был вызван. Вы должны запустить этот метод в after_action, чтобы убедиться, что вы не забыли authorize действие.

То же самое верно и для verify_policy_scoped, но policy_scope:

Кроме того, Пандит также добавляет verify_policy_scoped к контроллеру. Это вызовет исключение в жиле verify_authorized. Однако он отслеживает, если вместо authorize используется policy_scope. Это в основном полезно для действий контроллера, таких как index, которые находят коллекции с областью действия и не разрешают отдельные экземпляры.

В вашем случае исключение вызвано тем фактом, что вы не вызвали авторизацию в действии Devise::SessionsController#new.

Я думаю, что лучший способ справиться с этим - удалить after_action с ApplicationController и переместить их в подкласс.

Смежные вопросы