Rails Module Area

Given the following controller structure:

# 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 

One would expect Admin::PagesController inherit from Admin::ApplicationController , and that would happen. But I noticed that sometimes it inherits from ::ApplicationController .

So, I decided not to take any chances and changed the declaration of all controllers in /admin to specifically configure Admin::ApplicationController

 # admin/pages_controller.rb module Admin class PagesController < Admin::ApplicationController; end end 

It's good that this works, but from what I know, it was right in the first place. Why is Rails sometimes inherited from the wrong controller?

Admin::PagesController sometimes inherited from ApplicationController instead of Admin::ApplicationController , although both are in the same module Admin

+5
source share
2 answers

The problem is loading the rails development mode code: in general, the code is loaded when you try to do something with a constant (for example, a subclass of it) and this constant does not exist. This leads to a call to const_missing , and the rails use it to try to load the class (see the manual for a detailed description).

If neither ApplicationController nor Admin :: ApplicationController exist, then when you access your controller pages, the ruby ​​will hit this const_missing and try to load admin / application_controller.rb

However, if the ApplicationController is already loaded, then ruby ​​will not run const_missing , since it is completely legal for a class in the admin module to inherit something at the level.

The decision, as you say, should make explicit what you inherit. Personally, in my own applications, I use Admin::BaseController as a base class.

+4
source

Another option is to use require_dependency to point Rails to the correct file:

 # admin/application_controller.rb require_dependency 'admin/application_controller' module Admin class PagesController < ApplicationController end end 
+1
source

All Articles