Ruby on rails 如何定义与Rails autoloader一起使用的嵌套控制器?

Ruby on rails 如何定义与Rails autoloader一起使用的嵌套控制器?,ruby-on-rails,constants,autoload,Ruby On Rails,Constants,Autoload,假设我有两个定义为控制器的标准rails资源,每个都有自己的CRUD操作(index,show,等等) EmployeesController Employees::AssignmentController 目录看起来像- app/ controllers/ - employees_controller.rb employees/ - assignment_controller.rb 我正试图找出如何最好地定义第二个嵌套控制器来与Rails autoload

假设我有两个定义为控制器的标准rails资源,每个都有自己的CRUD操作(
index
show
,等等)

  • EmployeesController
  • Employees::AssignmentController
目录看起来像-

app/
  controllers/
    - employees_controller.rb
    employees/
      - assignment_controller.rb
我正试图找出如何最好地定义第二个嵌套控制器来与Rails autoloader一起工作

选项A-命名空间常量 如果我这样做-

class Employees::AssignmentController
在运行集成测试时,我的应用程序日志中出现以下错误:

LoadError:无法自动加载常量Employees::AssignmentController,应为/Users/jeeves/git/my project/app/controllers/Employees/assignment\u controller.rb来定义它>
它不喜欢将常量定义为单个命名空间-
Employees::AssignmentController

选项B-模块内的嵌套常量 如果我这样做-

模块员工
类赋值控制器<应用程序控制器
结束
结束
我实际上得到了与上面相同的
LoadError
错误

选项C-类内的嵌套常量 最后,如果我这样做了-

类员工
类赋值控制器<应用程序控制器
结束
结束
我得到
TypeError:Employees不是一个类,这是有意义的,因为外部
类没有定义。我试图通过添加一个带有空文件的显式
定义来修复它

 app/
   controllers/
     - employees_controller.rb
+    - employees.rb
     employees/
       - assignment_controller.rb
类员工
结束
这是有效的。但是让这个额外的虚拟文件挂在
app/controllers
中感觉很傻,尤其是当它本身不是控制器的时候

问题: 有没有正确的方法来处理上述情况?选项C是我唯一的选择吗?我是否正确地使用了名称空间,还是应该同时避免使用它们

谢谢

使用显式 筑巢。使用范围解析运算符可能会导致意外的结果 由于Ruby的词法范围(取决于 模块嵌套在定义点。

这种令人惊讶的行为的一个例子是:

class Employees::AssignmentController
  def index
    @rate = Rate.find(...)
  end
end
您希望Rate解析为
Employees::Rate
,但实际上它解析为
::Rate
,因为词法范围是
::

这是首选方法:

module Employees
  class AssignmentController
    def index
      @rate = Rate.find(...) # resolves to Employees::Rate
    end
  end
end
它将重新打开模块,并在正确的词法范围内定义一个新常量

至于备选方案C——这是可能的,因为Ruby中的类是模块(如果你不相信我的话,请检查
Class.concedens
),但它不被认为是好的形式,因为类应该是可以实例化的东西

rails生成器使用scoperesolution操作符以“错误”的方式完成此操作,但这实际上只是由于文件模板系统中的限制

那为什么会出现加载错误呢?
我真的不知道。这是首选的方法,没有明显的理由说明它在这种情况下不起作用。仔细检查一切。通过运行
spring stop
重新启动spring,然后重新启动服务器

这里需要注意的一点是,您使用的是singular
AssignmentController
,如果您声明的是singular resource,这是很好的,但如果用户可以有许多工作分配,并且您使用的是
resources:assignments
,则情况并非如此。