Ограничения просмотра индекса для различных ролей с использованием 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
РЕДАКТИРОВАТЬ: обновлено, чтобы справиться со случаем не быть администратором или суперпользователем