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
to inherit from Admin::ApplicationController
and it does. But I have noticed that sometimes it inherits from ::ApplicationController
.
So I decided not to risk it and changed declaration of all controllers in /admin
to specifically target Admin::ApplicationController
# admin/pages_controller.rb
module Admin
class PagesController < Admin::ApplicationController; end
end
Okay that works, but from what I know it was correct in the first place. Why Rails inherits from a wrong controller sometimes?
Admin::PagesController
sometimes inherits from ApplicationController
instead of Admin::ApplicationController
despite both being in the same module Admin
The problem here is rails' development mode code loading: in general code is loaded when you try to do something with a constant (eg subclass from it) and that constant doesn't exist. This results in const_missing
being called and rails uses it this to try to load the class (for a detailed description see the guide).
If neither ApplicationController nor Admin::ApplicationController exist then when you access your admin pages controller ruby will hit that const_missing and try to load admin/application_controller.rb
However if ApplicationController is already loaded then ruby won't fire const_missing
since it perfectly legal for a class in the admin module to inherit from something at the toplevel.
The solution as you say is to make explicit what you are inheriting from. Personally in my own apps I use Admin::BaseController
as the base class.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With