[英]Getting Pundit authorization working with Namespaces on Rails 5
關於讓Rails 5和Pundit授權使用命名空間的問題。
使用Pundit,在控制器中我想使用policy_scope([:admin, @car]
,它將使用位於以下位置的Pundit策略文件: app/policies/admin/car_policy.rb
。我在嘗試使用Pundit時遇到問題命名空間 - 沒有命名空間,它工作正常。
應用正在運行:
例如,我的命名空間用於admins
。
route.rb
文件如下所示:
# config/routes.rb
devise_for :admins
root: 'cars#index'
resources :cars
namespace :admin do
root 'cars#index'
resources :cars
end
我已經設置了Pundit ApplicationPolicy
並讓命名空間使用Pundit的authorize
方法: @record = record.is_a?(Array) ? record.last : record
@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
但我想使用Policy Scope
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)
但這不起作用:)。
非常感謝任何助理。
我在Pundit Github問題頁面上找到了這個: https : //github.com/elabs/pundit/pull/391
這修復了policy_scope的名稱空間處理,這是我想要的。
它更新了Pudit gem - > policy_scope!
lib/pundit.rb
方法。
從:
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應用程序中使用它? 它被稱為重載或猴子修補?
我在想在config/initializer
目錄中添加一個pundit.rb
並使用module_eval
但不確定如何在policy_scope!
執行此操作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
Medir在Pundit Github問題頁面上發布了該解決方案。
只需將application_policy.rb更改為:
class ApplicationPolicy
index? show?....
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
# @scope = scope
@scope = scope.is_a?(Array) ? scope.last : scope #This fixes the problem
end
def resolve
scope
end
end
end
然后你可以使用:
policy_scope([:admin, @cars])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.