我指的是我自己的问题Rails Nested Resources with Pundit Allowing Index,最后提出了一个有效的解决方案,但是在property_policy中没有更好的解决方案定义scope.where(?)或scope.select(?)?如何使用pundit resolve方法获取仅属于一个特定交易的所有属性?
我最终做了什么:
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 /属性,除了我有简单&#34; / properties&#34;的完整属性列表。非常感谢您的帮助。
**更新**
我终于去了
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
不确定这是否正确
答案 0 :(得分:0)
您要做的是将范围传递给策略 - 而不仅仅是一个类。
@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
,因为您可以假设用户是管理员。