ruby-on-rails 使用pundit resolve方法的嵌套资源的范围

xxslljrj  于 2022-12-20  发布在  Ruby
关注(0)|答案(1)|浏览(122)

I am referring to my own question Rails Nested Resources with Pundit Allowing Index and finally came up with a working solution but is there not any much better solution defining scope.where(?) or scope.select(?) in the property_policy? How to get all the properties that only belongs to one specific deal using the pundit resolve method?
我最终做的是:
属性_控制器. rb

class PropertiesController < ApplicationController
before_action :set_deal, except: [:index, :all]
before_action :set_property, only: [:show, :edit, :update, :destroy]

def all
  @properties = Property.all
  authorize @properties
end

def index
  @deal = Deal.find(params[:deal_id])
  @properties = policy_scope(Deal)
end

def set_deal
  @deal = Deal.find(params[:deal_id])
  # pundit ######
  authorize @deal
  ###############
end
(...)
end

属性_策略. rb

class PropertyPolicy < ApplicationPolicy
class Scope < Scope
def resolve
  scope.all if user.admin?
end
def all?
  user_is_admin?
end
def user_is_admin?
  user.try(:admin?)
end 
(...)
end

我更喜欢的是:
属性_控制器. rb

def index
  @deal = Deal.find(params[:deal_id])
  @properties = policy_scope(Property) # => for # @properties = @deal.properties
  authorize @deal
end

并在property_policy. rb中设置如下内容

def resolve
  # scope.where(???) if user.admin? # only an admin user can see the @deal.properties
  # or any other solution using scope
 end

作为一个提醒1交易有许多属性和1属性属于一个特定的交易。我的路线是嵌套交易/id/properties除了完整的属性列表,我有简单的"/properties "。非常感谢帮助。

    • 更新**

我终于去了
属性_控制器. rb

def index
  @deal = Deal.find(params[:deal_id])
  @properties = policy_scope(@deal.properties)
  authorize @properties, :index?
end

和属性_策略. rb中

class PropertyPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      user.admin? ? scope.all : scope.none
    end
  end
  def index?
    user_is_admin?
  end
  def user_is_admin?
    user.try(:admin?)
  end
end

不知道这是不是正确的方式

wwtsj6pe

wwtsj6pe1#

您要做的是向策略传递一个作用域-而不仅仅是一个类。

@properties = policy_scope(@deal.policies)

class PropertiesPolicy
  class Scope < Scope
    def resolve
      user.admin? ? scope.all : scope.none
    end
  end
end

控制器的另一个问题是authorize @deal将调用DealsPolicy#index?,这不是您想要的。
要授权一个索引操作,您需要使用模型类(而不是示例)调用authorize

def index
  authorize Property # calls PropertiesPolicy#index?
  @deal = Deal.find(params[:deal_id])
  @properties = policy_scope(@deal.properties)
end

在这种情况下,你不需要在Scope#resolve方法中做任何特殊的事情,只要返回scope就可以了,因为你可以假设用户是管理员。

相关问题