【问题标题】:How to override policy class in view如何在视图中覆盖策略类
【发布时间】:2020-08-04 18:58:33
【问题描述】:

我正在尝试使用Pundit gem,它可以让您像这样覆盖控制器中的策略类

def create
  @publication = find_publication # @publication.class => Post
  authorize @publication, policy_class: PublicationPolicy
  @publication.publish!
  redirect_to @publication
end

我尝试覆盖视图中的策略类,如下所示,但收到错误 unknown keyword: :policy_class

<% if policy(@publication, policy_class: PublicationPolicy).create? %>

【问题讨论】:

  • 您是在问“为什么authorize 采用policy 没有的选项?”
  • 是的。我需要相同的东西,很高兴看到 authorize 采用允许您覆盖控制器中的策略类的选项,但我无法使用 [corresponding] 策略函数类似地覆盖视图中的策略类
  • 如果您在这里没有得到答案,可能值得参与 Pundit 特定论坛或该项目的问题以请求该功能。

标签: ruby-on-rails ruby rubygems ruby-on-rails-6 pundit


【解决方案1】:

policy 只是根据您传递给它的资源查找策略的快捷方式。

# Retrieves the policy for the given record.
#
# @see https://github.com/varvet/pundit#policies
# @param user [Object] the user that initiated the action
# @param record [Object] the object we're retrieving the policy for
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
# @return [Object, nil] instance of policy class with query methods
def policy(user, record)
  policy = PolicyFinder.new(record).policy
  policy&.new(user, pundit_model(record))
rescue ArgumentError
  raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
end

它真的只是MyPolicy.new(user, record) 的缩写。添加policy_class 选项将完全没有意义。如果您已经知道自己想要什么,为什么还要动态查找?

authorize on 如果不允许,则会引发 NotAuthorizedError 并动态找出您尝试执行的操作,因此具有该选项是有意义的。

【讨论】:

  • 谢谢,有道理。我可以这样做然后&lt;% if PublicationPolicy.new(current_user, @publication).create? %&gt;
  • 是的,但是您可能应该将策略作为本地变量或实例变量从控制器传递,因为您应该使视图尽可能简单。
猜你喜欢
  • 1970-01-01
  • 2011-05-11
  • 2011-06-19
  • 2021-12-19
  • 2021-11-16
  • 2018-02-05
  • 1970-01-01
  • 2021-09-14
  • 2017-02-11
相关资源
最近更新 更多