给出以下控制器结构:
# application_controller.rb
class ApplicationController < ActiveController::Base; end
# pages_controller.rb
class PagesController < ApplicationController; end
# admin/application_controller.rb
module Admin
class ApplicationController < ::ApplicationController; end
end
# admin/pages_controller.rb
module Admin
class PagesController < ApplicationController; end
end
人们希望Admin::PagesController
继承Admin::ApplicationController
而且确实如此。但我注意到它有时会继承自::ApplicationController
。
所以我决定不冒风险,并将/admin
中所有控制器的声明更改为专门定位Admin::ApplicationController
# admin/pages_controller.rb
module Admin
class PagesController < Admin::ApplicationController; end
end
好的,但是从我知道它首先是正确的。为什么Rails有时会从错误的控制器继承?
Admin::PagesController
有时继承自ApplicationController
而不是Admin::ApplicationController
,尽管两者都在同一个module Admin
答案 0 :(得分:4)
这里的问题是rails&#39;开发模式代码加载:通常,当您尝试使用常量(例如,来自它的子类)执行某些操作时,会加载代码,并且该常量不存在。这导致const_missing
被调用,rails使用它来尝试加载类(有关详细说明,请参阅the guide)。
如果ApplicationController和Admin :: ApplicationController都不存在,那么当您访问管理页面控制器时,ruby会点击const_missing并尝试加载admin / application_controller.rb
但是如果已经加载了ApplicationController,那么ruby就不会激活const_missing
,因为管理模块中的一个类完全合法地从顶层的东西继承。
您所说的解决方案是明确您继承的内容。我个人在自己的应用程序中使用Admin::BaseController
作为基类。
答案 1 :(得分:1)
另一种选择是使用require_dependency
将Rails指向正确的文件:
# admin/application_controller.rb
require_dependency 'admin/application_controller'
module Admin
class PagesController < ApplicationController
end
end