13

私は Rails の初心者で、次のポリシー ( Punditを使用)に問題が@recordあり@fooます。

class BarPolicy < ApplicationPolicy
  def show?
    @record.foo_id == @foo
  end
end

2 番目のパラメーターを専門家メソッド (@foo) に渡す良い方法を見つけることができません。

私は次のようなことをしたいと思います:

class BarsController < ApplicationController
  def test
    authorize bar, @foo, :show? # Throws ArgumentError
    ...
  end
end

ただし、Pundit 承認メソッドでは 2 つのパラメーターしか使用できません。この問題を解決する方法はありますか?

ありがとう!

4

3 に答える 3

17

ここで答えを見つけました。

これが私のやり方です:

pundit_userに関数を追加しApplicationControllerます。

class ApplicationController < ActionController::Base
include Pundit
def pundit_user
    CurrentContext.new(current_user, foo)
end

CurrentContextクラスを作成します。

/lib/pundit/current_context.rb
class CurrentContext
  attr_reader :user, :foo

  def initialize(user, foo)
    @user = user
    @foo = foo
  end
end

Pundit の初期化メソッドを更新します。

class ApplicationPolicy
  attr_reader :user, :record, :foo

  def initialize(context, record)
    @user = context.user
    @foo = context.foo
    @record = record
  end
end
于 2015-01-30T15:56:30.123 に答える
0

Punditに余分なパラメータを渡すのは悪いコーディングだというこの考えが何であるか理解できません。確かに、それは大きなケースステートメントのようなものです。より適切な設計で回避できる場合は回避できますが、通常、承認ロジックを他のファイルに分散させるか、追加情報を Pundit に渡すかの選択に直面します。

これは、Pundit クラスを使用して、ユーザーが特定の列での並べ替えを許可されているかどうかを確認できるようにするために作成したコードです (resource_class は、関連付けられたコントローラーで関連付けられたアクティブレコード クラスを返す、私が作成した別のメソッドです)。

    def authorize_sort(column, record = resource_class)
        Pundit.policy!(user, record)
        unless policy.allow_sort?(column)
            raise NotAuthorizedError, "Not authorized to sort on column #{column} on record #{record}"
        end
    end

承認ロジックをより多くのクラスに分散させたくない場合や、他のユーザーが見ることができないフィールドでユーザーが並べ替えられるようにしたい場合、これは避けられません。特別な Active record Sort オブジェクトを作成しないと、返される単一のオブジェクトのプロパティではなく、それらが並べ替えられる列のプロパティであるため、これは避けられません。

于 2021-10-20T15:38:54.057 に答える