我遵循了Pundit的典型授权教程,因此遇到了问题。我是Ruby on Rails的新手,所以我真的不太了解这是什么原因。我用谷歌搜索其他堆栈问题,但没有像我一样使用角色进行授权。随时发表评论并留下建议。
(错误发生在users#index;我以讲师身份登录,但不允许我进入用户的索引页面。]
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@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
class UserPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all
end
def create?
can_make_changes?
end
def update?
can_make_changes?
end
def edit?
can_make_changes?
end
def can_make_changes?
@user.role == "Instructor"
end
end
end
class UsersController < ApplicationController
before_action :authenticate_user!, :find_user, only: [:edit, :update,:destroy]
def index
@users = User.all
authorize User
end
#other methods...
private
def find_user
@user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:first_name, :last_name, :login, :student_id, :citizen_id, :department_name, :instructor_id)
end
end
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
include Pundit
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name, :citizen_id, :student_id, :instructor_id, :department_name, :login, :role])
end
def user_not_authorized
flash[:warning] = "You are not authorized to perform this action."
redirect_to(request.referrer || courses_path)
end
end
class User < ApplicationRecord
validates :first_name, presence: true, format: { with: /\A[a-zA-Z]+\z/, message: "only allows letters" }
validates :last_name, presence: true, format: { with: /\A[a-zA-Z]+\z/, message: "only allows letters" }
validates :login, presence: true, format: { with: /\A[a-zA-Z0-9]+\z/, message: "no special characters allowed" }
validates :citizen_id, presence: true, uniqueness: true, format: { with: /\A[0-9]+\z/, message: "only allows numbers" }
validates :role, presence: true
validates :password, presence: true, length: { minimum: 6 }
devise :database_authenticatable, :registerable,
:recoverable, :rememberable
enum role: {'Student'=>'Student','Instructor'=>'Instructor','Other'=>'Other'}
has_and_belongs_to_many :courses
has_and_belongs_to_many :groups
has_many :projects
end
您需要向user_policy.rb添加方法以允许访问索引。
def index?
can_make_changes?
end
否则,根据application_policy.rb,它默认为false
。
然后,您需要更新users_controller.rb文件中的索引方法,以仅返回范围内的记录。
def index
@users = policy_scope(User)
end
根据您的情况,根据UserPolicy all
方法,作用域将为resolve
。