使用Pundit的各种角色的索引视图限制

时间:2014-12-29 03:05:44

标签: ruby-on-rails ruby pundit

我正在尝试为三个角色创建一个show view。管理员,超级用户和用户。管理员应该看到所有用户。超级用户应该只看到用户,用户不应该看到任何人。当我在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 个答案:

答案 0 :(得分: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

编辑:更新以处理不是管理员或超级用户的情况