12

在我的项目中,我有非常常见的命名空间“admin”。

namespace :admin do
    resources :users, except: :show
end

我使用 Pundit gem 设置正确的授权,但我发现很难与命名空间中的控制器一起使用。我的政策组织如下

-policies
    -admin
        user_policy.rb
    application_policy.rb
    admin_policy.rb
    awesome_policy.rb

非常类似于控制器。

但是,当我在控制器内部使用“授权”方法时,我只得到一个错误,通知该应用程序“无法找到 UserPolicy”。我的 UserPolicy 看起来像这样:

class Admin::UserPolicy < AdminPolicy
end

那么问题是什么,我应该怎么做才能让 Pundit 在命名空间中看到这些策略?

4

4 回答 4

4

使用新的合并提交,您可以做到这一点。

它会自动工作。

更新:

从 0.3 版本开始有效删除而不替换功能。但是可以在github上的命名空间分支中获得命名空间功能。

您可以在 github 上查看 issue 中有关功能的讨论。

我对想要使用权威人士命名空间的人的建议 - 不要使用。在过滤器之前进行过滤以访问管理仪表板等受限区域,并将授权模型规则保留在权威文件中。这样,您就可以在没有黑客和问题的情况下使用 pundit。

于 2014-05-28T04:44:25.323 回答
3

简短的回答:你不能让 Pundit 使用控制器命名空间特定的策略。

长答案:Pundit 会查看资源(模型)以确定要使用的 Policy 类,因此每当您将User模型的实例作为资源传入时,它都会查找UserPolicy,而不是Admin::UserPolicy

这里这里这里

可以在模型上指定一个策略类User,但这并不能真正解决您的命名空间控制器问题,因为 Pundit 将从模型中派生策略类,无论您在哪里授权。

于 2014-02-11T04:56:35.503 回答
2

虽然 onemanstartup 提到它现在应该自动工作,但我无法让命名空间策略工作,但这是我认为可以接受的。

在您的情况下,在 AdminPolicy 中,我添加了自定义操作名称,例如

def new_user?
  some code
end

然后在我的 Admin::UserController#new 操作中

def new
  authorize @user, :new_user?
end
于 2014-08-04T02:34:45.553 回答
1

刚来这里是因为同样的问题。使用 pundit v2.1.0,这可以通过覆盖policy_scopeauthorize在控制器中实现。我为类似的设置做了什么:

module Admin
  class ModuleController < ModuleController
    private

    def policy_scope(scope)
      super([:admin, scope])
    end

    def authorize(record, query = nil)
      super([:admin, record], query)
    end
  end
end

然后只需使用通常的方式在控制器中使用您的策略,然后它将从您的Admin命名空间中获取策略。

这也在https://github.com/varvet/pundit#policy-namespacing的自述文件中进行了描述

如果您需要的不仅仅是当前用户和记录,那么具有两个输入参数的 Pundit 策略将很有帮助。

于 2020-11-07T11:03:23.213 回答