-->

Index View Restrictions for Various Roles using Pu

2019-04-17 01:58发布

问题:

I'm trying to create a show view for three roles. Admin, super user, and user. An admin should see all of the users. A super user should see only users and a user should not see anyone. When I used the commented out policy method in the resolve for else user.super_user? would give me unsupported: TrueClass error. Any suggestions are welcomed.

Users Controller

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

User Policy

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

updated Users Controller

class UsersController < ApplicationController
  before_filter :authenticate_user!
  after_action :verify_authorized

  def index
    @users = policy_scope(User)
  end
end

Correct Answer

I figured out what I needed to do. I was calling the role incorrectly. Updated scope below.

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

controller

class UsersController < ApplicationController
  before_filter :authenticate_user!
  after_action :verify_authorized

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

回答1:

Your resolve method should use elsif:

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

or not check for the super user at all and just depend on checking the authorization of the user before the result is used:

# 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

EDIT: updated to deal with the case of not being an admin or super user