【问题标题】:Scope for nested resources using pundit resolve method使用权威解析方法的嵌套资源范围
【发布时间】:2017-06-26 05:54:22
【问题描述】:

我指的是我自己的问题Rails Nested Resources with Pundit Allowing Index 并最终提出了一个可行的解决方案,但是在 property_policy 中定义 scope.where(?) 或 scope.select(?) 没有更好的解决方案吗?如何使用权威解析方法获取仅属于一个特定交易的所有属性?

我最终做了什么:

properties_controller.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

property_policy.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

我想要更好的:

properties_controller.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”的完整属性列表。非常感谢您的帮助。

** 更新 **

我终于去了

properties_controller.rb

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

在property_policy.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

不确定是否正确

【问题讨论】:

    标签: ruby-on-rails scope nested pundit


    【解决方案1】:

    您想要做的是将范围传递给策略 - 而不仅仅是一个类。

    @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.policies)
    end
    

    在这种情况下,您实际上不必在 Scope#resolve 方法中做任何特别的事情。只需返回 scope,因为此时您可以假设用户是管理员。

    【讨论】:

    • 非常感谢 Max,但使用授权不起作用:index 我收到错误 unable to find policy "IndexPolicy" for ":index" 如果我没有在 index 方法中授权任何内容,任何用户都可以看到不是我的属性想要。 user.admin? ? scope.all : scope.none 也不是我真正想要的,它更像是全部或根本不授予对页面的访问权限。
    • Max 我想我现在明白你的意思了。请看我的更新。我已经定义了范围和索引? property_policy 中的方法并在控制器中更改了authorize @properties, :index?。这是你的意思吗?如果您能确认我正确理解您需要定义范围和索引,我将不胜感激?限制页面可见性的方法。谢谢
    • 啊,对不起,我错过了文档 - 如果您没有要使用 authorize Property 类调用授权的实例,您应该在方法顶部调用它以抛出经过身份验证的用户出去。查看我的编辑
    • 如果你用符号调用它,它应该是authorize :properties, :index?,这就是你处理无头控制器的方式。
    • 感谢 Max 的解释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多