獲取使用命名空間的Rails 5和Pundit授權的問題。使用命名空間獲得Pundit授權使用Rails 5
有了Pundit,我想在控制器中使用policy_scope([:admin, @car]
,它將使用位於app/policies/admin/car_policy.rb
中的Pundit策略文件。我在嘗試使用此命名空間的權威人士遇到問題 - 沒有命名空間,它工作正常。
應用程序正在運行:
- Rails的5
- 設計認證
- 權威人士授權
My命名空間是admins
例如。
- 標準用戶>http://garage.me/cars
- 管理員用戶>http://garage.me/admin/cars
的route.rb
文件看起來像:
# config/routes.rb
devise_for :admins
root: 'cars#index'
resources :cars
namespace :admin do
root 'cars#index'
resources :cars
end
我設置一個權威人士ApplicationPolicy
,並獲得名稱空間與Pundit一起工作的authorize
方法:@record = record.is_a?(Array) ? record.last : record
# app/policies/application_policy.rb
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record.is_a?(Array) ? record.last : record
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
在Admin::CarsController
這個作品authorize [:admin, @cars]
class Admin::CarsController < Admin::BaseController
def index
@cars = Car.order(created_at: :desc)
authorize [:admin, @cars]
end
def show
@car = Car.find(params[:id])
authorize [:admin, @car]
end
end
但我想用政策範圍
class Admin::CarPolicy < ApplicationPolicy
class Scope < Scope
def resolve
if user?
scope.all
else
scope.where(published: true)
end
end
end
def update?
user.admin? or not post.published?
end
end
在Admin::CarsController
class Admin::CarssController < Admin::BaseController
def index
# @cars = Car.order(created_at: :desc) without a policy scope
@cars = policy_scope([:admin, @cars]) # With policy scope/doesn't work because of array.
authorize [:admin, @cars]
end
def show
# @car = Car.find(params[:id]) without a policy scope
@car = policy_scope([:admin, @car]) # With policy scope/doesn't work because of array.
authorize [:admin, @car]
end
end
我得到一個錯誤,因爲Pundit沒有在尋找Admin::CarPolicy
。我認爲這是因爲它是一個數組。
我想在控制器中我可以做一些像policy_scope(Admin::Car)
但這不起作用:)。
任何助手非常感謝。
更新
我發現這對權威人士Github上的問題頁:https://github.com/elabs/pundit/pull/391
這修正了命名空間處理爲policy_scope這正是我想要的。
它更新lib/pundit.rb
中的Pudit gem - >policy_scope!
方法。
來源:
def policy_scope!(user, scope)
PolicyFinder.new(scope).scope!.new(user, scope).resolve
end
要:
def policy_scope!(user, scope)
model = scope.is_a?(Array) ? scope.last : scope
PolicyFinder.new(scope).scope!.new(user, model).resolve
end
我的問題是,如何我在Rails應用程序中使用它?它被稱爲超載或猴子補丁?
我想加入pundit.rb
在config/initializer
目錄和使用module_eval
但不確定如何做到這一點的policy_scope!
裏面module Pundit
和class << self
。
我以爲這會工作,但它不會 - 假設它是因爲policy_scope!
是在class << self
之內。
Pundit::module_eval do
def policy_scope!(user, scope)
model = scope.is_a?(Array) ? scope.last : scope
PolicyFinder.new(scope).scope!.new(user, model).resolve
end
end