Rails 5とPundit認可が名前空間で動作することについての質問。Rails 5上の名前空間で働くPundit認可の取得
Punditのコントローラーではpolicy_scope([:admin, @car]
を使用しましたが、これはapp/policies/admin/car_policy.rb
にあるPunditポリシーファイルを使用します。私はこの名前空間で作業するPunditに問題を抱えています。名前空間がなければうまくいきます。
アプリケーションが実行されている:
- Railsの5
- 工夫を認証
- 評論家のための認可のために
私の名前空間には、例えばadmins
ためです。私はセットアップ評論家ApplicationPolicy
をしましたし、取得するために
# config/routes.rb
devise_for :admins
root: 'cars#index'
resources :cars
namespace :admin do
root 'cars#index'
resources :cars
end
:
- 標準ユーザー>http://garage.me/cars
- 管理者ユーザー>http://garage.me/admin/cars
はroute.rb
ファイルは次のようになりますPunditで働く名前空間さんauthorize
方法:Admin::CarsController
で@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
これは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
に動作します。しかし、私は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
で
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
ポリシースコープを使用したいです
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アプリケーションでこれを使うのですか、ですか?それは過負荷または猿のパッチと呼ばれていますか?
私はpolicy_scope!
がmodule Pundit
とclass << self
内にあるとして、これを行う方法をpundit.rb
でconfig/initializer
ディレクトリを追加し、module_eval
を使用しますがわからない考えていました。
これはうまくいくと思いましたが、それはありません。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