2017-11-06 10 views
1

私はPunditを自分のアクティブな管理者と統合し、設定を作成しようとしています。しかし、アプリは変わって動作します。これは、モデル/レコードをcurrent_userとして取り込みます。NoMethodError未定義のメソッド `admin? ' nilClass Pundit、Devise Rails

私のポリシーファイル:

class AdminUserPolicy 
    attr_reader :current_user, :model 

    def initialize(current_user, model) 
    Rails.logger.info '--------------- initialize called-------------------' 
    Rails.logger.info current_user 
    Rails.logger.info model 
    @current_user = current_user 
    @record = model 
    end 

    def index? 
    @current_user.admin? 
    end 
end 

コントローラ:次のように

controller do 
    include Pundit 
    protect_from_forgery 
    rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized 
    before_action :authenticate_admin_user! 

    def index 
     authorize current_admin_user 
     super 
    end 

    private 

     def user_not_authorized 
      flash[:alert]="Access denied" 
      redirect_to (request.referrer || admin_root_path) 
     end 
end 

ログは次のとおりです。

--------------- initialize called---------------------------------------- 

#<AdminUser:0x007f27733f8a80> 
Completed 500 Internal Server Error in 364ms (ActiveRecord: 312.8ms) 



NoMethodError (undefined method `admin?' for nil:NilClass): 

app/policies/admin_user_policy.rb:13:in `index?' 
app/admin/dashboard.rb:19:in `index' 
    Rendering /usr/local/rvm/gems/ruby-2.3.4/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout 
    Rendering /usr/local/rvm/gems/ruby-2.3.4/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb 
    Rendered /usr/local/rvm/gems/ruby-2.3.4/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (4.8ms) 
    Rendering /usr/local/rvm/gems/ruby-2.3.4/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb 
    Rendered /usr/local/rvm/gems/ruby-2.3.4/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.5ms) 
    Rendering /usr/local/rvm/gems/ruby-2.3.4/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb 
    Rendered /usr/local/rvm/gems/ruby-2.3.4/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.1ms) 
    Rendered /usr/local/rvm/gems/ruby-2.3.4/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (39.5ms) 

奇妙な部分は、ログによると、current_user=nilmodel=#<AdminUser:0x007f27733f8a80>

です

私は

def index? 
    @record.admin? 
end 

としてモデルと私のポリシーファイルをCURRENT_USERを入れ替えそして、それは働きます! 私はこの奇妙な動作を理解していません。

答えて

1

Pundit policy docは、current_userメソッドを呼び出して、Policyクラス内のinitializeメソッドの最初の引数に何を送信するかを取得します。あなたがcurrent_admin_userを使用してログインしているユーザの現在取得するActiveAdminを設定している場合は、そのようなあなたのApplicationControllerクラスで評論家のデフォルトのメソッドをオーバーライドする必要があります。Ref

class ApplicationController < ActionController::Base 
    // ... 
    def pundit_user 
    current_admin_user // or whatever based on ActiveAdmin initializer config 
    end 
end 

定義されたポリシーの作業をするためには、あなたコントローラのアクション内で対応するポリシーモデルのインスタンスを使用してauthorizeを呼び出す必要があります。あなたはPostPolicyを持っていて、updateアクションを許可する、あなたが次のことを行う必要があるのであれば:

controller do 
    def update 
    @post = Post.find(params[:id]) 
    authorize @post // the current user will be automatically sent to the PostPolicy 
    super 
    end 
end 

authorize方法が自動的にPostが一致PostPolicyクラスを持っていることを推測し、このクラスをインスタンス化し、中に手渡し現在のユーザーと指定されたレコード。次に、アクション名から、このポリシーのインスタンスでupdate?を呼び出す必要があることを推測します。ユーザーがすべてのユーザーの一覧を表示する前に承認される必要があることをしたい場合、あなたのケースでは、これらすべてを持つ

unless PostPolicy.new(current_user, @post).update? 
    raise Pundit::NotAuthorizedError, "not allowed to update? this #{@post.inspect}" 
end 

:このケースでは、authorizeはこのような何かをやっているだろうと想像することができますすでに完了しているようにAdminUserPolicyを定義することができます。チェックしたいパーミッションの名前がアクション名と一致しない場合、その後、あなたのAdminUserController

controller do 
    def index 
    @users = AdminUser.all 
    authorize @users // NOT `authorize current_admin_user` 
    super 
    end 
end 

indexアクションであなたはauthorizeに2つ目の引数を渡すことができます。例:

def publish 
    @post = Post.find(params[:id]) 
    authorize @post, :update? 
    @post.publish! 
    redirect_to @post 
end 
+0

ありがとうございました!それは多くのものをクリアする。 '' @users = Admin.all'''や '' @ post = Post.find() ''のようなクエリは不要な処理に追加されます。ユースケースはユーザが使用できるかどうかを知るだけなのでインデックスや更新などのメソッドのようなものです。それらを分化政策にリダイレクトする方法はありますか?または、current_admin_userを引き続き使用できますか? –

+0

それを知ってうれしい! –

+0

私はちょうど "このユーザが見ることができる"か "このユーザを編集できますか"を知りたいと思うだけです。私は@post変数には関係しません。したがって、それらを照会することは不要です。しかし、私がそれらを省略すると、どのポリシーをチェックインするのかわかりませんでした。だから私は単に "権限:インデックス?"入力なし。 –

関連する問題