fir*_*dev 5 ruby inheritance ruby-on-rails
给定以下控制器结构:
# 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
Run Code Online (Sandbox Code Playgroud)
人们会期望Admin::PagesController继承Admin::ApplicationController而且确实如此.但我注意到它有时会继承自::ApplicationController.
因此,我决定不冒险,并将所有控制器的声明更改/admin为特定目标Admin::ApplicationController
# admin/pages_controller.rb
module Admin
class PagesController < Admin::ApplicationController; end
end
Run Code Online (Sandbox Code Playgroud)
好的,但是从我知道它首先是正确的.为什么Rails有时会从错误的控制器继承?
Admin::PagesController 有时继承ApplicationController而不是Admin::ApplicationController尽管两者都是相同的module Admin
这里的问题是rails的开发模式代码加载:一般来说,当您尝试使用常量(例如它的子类)执行某些操作并且该常量不存在时,就会加载代码。这会导致const_missing被调用,rails 使用它来尝试加载类(有关详细说明,请参阅指南)。
如果 ApplicationController 和 Admin::ApplicationController 都不存在,那么当您访问管理页面时,控制器 ruby 将命中 const_missing 并尝试加载 admin/application_controller.rb
但是,如果 ApplicationController 已经加载,那么 ruby 将不会触发const_missing,因为管理模块中的类从顶层继承是完全合法的。
正如你所说的解决方案是明确你继承的内容。就我个人而言,我在自己的应用程序中使用它Admin::BaseController作为基类。