使用 pundit resolve 方法的嵌套资源范围
Scope for nested resources using pundit resolve method
我指的是我自己的问题 Rails Nested Resources with Pundit Allowing Index 并最终提出了一个可行的解决方案,但是没有更好的解决方案来定义 scope.where(?) 或 scope.select(? ) 在 property_policy 中?如何使用 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 笔 属性 属于一个特定的交易。我的路线是嵌套的 deals/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
不确定这样是否正确
您要做的是将范围传递给策略 - 而不仅仅是 class。
@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?
,这不是您想要的。
要授权要使用模型 class(而不是实例)调用 authorize
的索引操作:
def index
authorize Property # calls PropertiesPolicy#index?
@deal = Deal.find(params[:deal_id])
@properties = policy_scope(@deal.policies)
end
在那种情况下,您实际上不必在 Scope#resolve
方法中做任何特别的事情。只需 return scope
因为此时您可以假设用户是管理员。
我指的是我自己的问题 Rails Nested Resources with Pundit Allowing Index 并最终提出了一个可行的解决方案,但是没有更好的解决方案来定义 scope.where(?) 或 scope.select(? ) 在 property_policy 中?如何使用 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 笔 属性 属于一个特定的交易。我的路线是嵌套的 deals/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
不确定这样是否正确
您要做的是将范围传递给策略 - 而不仅仅是 class。
@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?
,这不是您想要的。
要授权要使用模型 class(而不是实例)调用 authorize
的索引操作:
def index
authorize Property # calls PropertiesPolicy#index?
@deal = Deal.find(params[:deal_id])
@properties = policy_scope(@deal.policies)
end
在那种情况下,您实际上不必在 Scope#resolve
方法中做任何特别的事情。只需 return scope
因为此时您可以假设用户是管理员。