在MainApp以外的命名空间中使用CanCan的load_and_authorize_resource功能。

6
我在我的Rails应用程序中使用CanCan进行权限管理,其中我为一些通用表单功能构建了自己的引擎。我希望限制系统中的权限,以便用户无法自由访问我的引擎控制器的操作。这些控制器大部分只是使用7个REST动作,因此我想在每个控制器的顶部使用CanCan的load_and_authorize_resource
然而,当我像这样编写我的代码时:
    module MyEngine
      class FormController < ApplicationController
        load_and_authorize_resource
        ...
      end
    end

我遇到了这个错误:

    uninitialized constant Form

我的猜测是`load_and_authorize_resource`中的自动加载程序与我的`MainApp`命名空间相关,并且没有意识到我正在使用不同的命名空间调用它,因此会执行像`Form.find(params[:id])`这样的调用,而不是`MyEngine::Form.find(params[:id])`。
如果是这种情况,我该怎么办?这并不是什么大问题,因为`authorize!`仍然正常工作,所以我可以在每个动作中单独定义授权,但如果能够使用`load_and_authorize_resource`方法会更加清晰明了。

3个回答

9

CanCan无法找到命名空间模型。尝试指定类:

load_and_authorize_resource class: MyEngine::Form

6
似乎是在CanCan::ControllerResource#namespace中出现了一个bug:
def namespace
  @params[:controller].split("::")[0..-2]
end

如您所见,它试图通过::来分割控制器路径,但实际上控制器路径的形式是my_engine/my_controller
因此修复方法非常简单:
def namespace
  @params[:controller].split("/")[0..-2]
end

想知道他们为什么会错过这么个愚蠢的漏洞,那我就给他们发一个拉取请求吧。

P.S. 我刚刚注册了,准备来回答问题。8)


1
哦!更有趣的是:他们似乎忘记将修复合并到“master”分支。 - Alexander Senko
太好了,这正是我所需要的! - Taylor Williams
1
此问题已在1.6.10版本中得到修复。 - Jared Beck

3

如果模型类的命名空间与控制器不同,您需要指定:class选项。

module MyEngine
  class FormController < ApplicationController
    load_and_authorize_resource :class => MyEngine::Form
    ...
  end
end

我得到了这个错误:未初始化常量MyEngine :: Form - Artem P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接