3

私のプロジェクトの 1 つで、私は pundit gem の使用を開始しました。次のような非常に単純なポリシーがあります。

class CompanyPolicy < ApplicationPolicy
  def index?
    true if user.is_a? Administrator
  end

  def new?
    true if user.is_a? Administrator
  end

  def create?
    new?
  end

  def edit?
    true if user.is_a? Administrator
  end

  def update?
    edit?
  end
end

問題は、これを繰り返さないようにするにはどうすればよいかということです。

true if user.is_a? Administrator
4

4 に答える 4

6

私は次のようなトリックを行います:

class ApplicationPolicy

  private

  def self.permit_owner_to(*actions)
    actions.each do |action|
      define_method("#{action}?") do
        owner?
      end
    end
  end

  def owner?
    # owner logic
  end

end

そして、それを他のポリシーで使用しました

class ItemPolicy < ApplicationPolicy

  permit_owner_to :show, :update, :destroy, :confirm

end
于 2015-02-16T12:15:02.853 に答える
2

実際にこれを削除する必要はないと思います。これを繰り返すことで、このユーザーがこのメソッドにアクセスするには管理者でなければならないことを明示的に示しています。ただし、必要に応じて、プライベート メソッドを作成できます。

class CompanyPolicy < ApplicationPolicy
  def index?
    admin?
  end

  def new?
    admin?
  end

  def create?
    new?
  end

  def edit?
    admin?
  end

  def update?
    edit?
  end

  private 
     def admin?
        user.is_a? Administrator
     end
end

これは個人の好みの問題だと思います。

于 2015-02-16T09:37:42.713 に答える
1

を使用できますalias_method

class CompanyPolicy < ApplicationPolicy
  def index?
    user.is_a? Administrator
  end

  alias_method :create?, :index?
  alias_method :update?, :index?
end

ApplicationPolicyおそらく既に含まれている基本クラスがあります。

def new?
  create?
end

def edit?
  update?
end

したがって、サブクラスでこれらのメソッドを繰り返す必要はありません。

.is_a?を返すtruefalse、明示的に返す必要はありませんtrue if true

それはもっと簡潔ですよね?:)

于 2015-11-20T03:05:41.203 に答える
0

上記の回答を組み合わせて、次のことを思いつきました。

class ApplicationPolicy
  attr_reader :user

  def initialize(user)
    @user = user
  end

  def self.permit(roles, options)
    return if options[:to].none?

    options[:to].each do |action|
      define_method("#{action}?") do
        return @user.roles? Array.wrap(roles) if options[:when].blank?

        send(options[:when]) and @user.roles? Array.wrap(roles)
      end
    end
  end
end

これにより、次のように使用できます。

class CommentPolicy < ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @record = record
    super(user)
  end

  permit %i[admin member], to: %i[show edit destroy update], when: :created_by_user

  def created_by_user
    @record.user == @user
  end
end

permit :admin, to: %i[index update edit]

同様に動作します

userモデルからの私のロールメソッドは次のようになります:

def roles?(user_roles)
    user_roles.each do |role|
      return true if role?(role)
    end
    false
  end

  def role?(role)
    roles.any? { |r| r.name.underscore.to_sym == role }
  end
于 2021-12-08T11:36:29.997 に答える