Ограничения просмотра индекса для различных ролей с использованием Pundit

Я пытаюсь создать представление для трех ролей. Администратор, супер пользователь и пользователь. Администратор должен видеть всех пользователей. Суперпользователь должен видеть только пользователей, а пользователь не должен никого видеть. Когда я использовал закомментированный метод политики в разрешении для else user.super_user? дал бы мне unsupported: TrueClass ошибка. Любые предложения приветствуются.

Контроллер пользователей

def index
  @users = policy_scope(User)
  authorize User
end

Политика пользователя

class UserPolicy
 attr_reader :current_user, :model

 def initialize(current_user, model)
   @current_user = current_user
   @user = model
 end

 class Scope
   attr_reader :user, :scope

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

   def resolve
     if user.admin?
       scope.all
     else user.super_user?
       scope.where(user.role = 'user' )
       # scope.where(user.role != 'admin') [this would not work in the views, but it would work in rails c]
       end
     end
   end

  def index?
    @current_user.admin? or @current_user.super_user?
  end
end

обновлен контроллер пользователя

class UsersController < ApplicationController
  before_filter :authenticate_user!
  after_action :verify_authorized

  def index
    @users = policy_scope(User)
  end
end

Правильный ответ

Я понял, что мне нужно сделать. Я назвал роль неправильно. Обновленная сфера ниже.

class UserPolicy
  attr_reader :current_user, :model

  def initialize(current_user, model)
    @current_user = current_user
    @user = model
  end

  class Scope
    attr_reader :user, :scope

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

    def resolve
      if user.admin?
        scope.all
      else user.super_user?
        scope.where(role: 'user' )
      end
    end
  end

  def index?
    @current_user.admin? or @current_user.super_user?
  end

контроллер

class UsersController < ApplicationController
  before_filter :authenticate_user!
  after_action :verify_authorized

  def index
    @users = policy_scope(User)
    authorize @users
  end

1 ответ

Решение

Ваш метод разрешения должен использовать elsif:

# Safer option
def resolve
   if user.admin?
     scope.all
   elsif user.super_user?
     scope.where(user.role = 'user' )
   else
     scope.none
   end
end

или вообще не проверять суперпользователя и просто зависеть от проверки авторизации пользователя перед использованием результата:

# This option is the same as the code you added to your question
# but doesn't include the unnecessary check
def resolve
   if user.admin?
     scope.all
   else
     scope.where(user.role = 'user' )
   end
end

РЕДАКТИРОВАТЬ: обновлено, чтобы справиться со случаем не быть администратором или суперпользователем

Другие вопросы по тегам