2017-02-25 20 views
4

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 

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 Punditclass << self内にあるとして、これを行う方法をpundit.rbconfig/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 

答えて

1

MedirはPundit Github Issuesページにこのソリューションを掲載しました。あなたはその後、使用することができます

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]) 

ちょうどにあなたのapplication_policy.rbを変更します

関連する問題