In short, use explicit module namespacing or avoid complex namespacing as often as possible when inheriting classes.
Class and Module constants depends on order of autoload-paths lookup (a Ruby on Rails feature), more on that below. Because of this, class discoverability can vary depending on the name and location of an inheriting class. When multiple classes share the same name, as is the case in our Rails app, this subtlety can impact implicit class inheritance.
Ruby on Rails has two main algorithms for constant look up in its
autoload_paths (by default all subdirectories of
app in the application and engines present at boot time, and
The values of
autoload_paths can be inspected with following command:
$ bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths'
.../app/assets .../app/controllers .../app/helpers .../app/mailers .../app/models .../app/resources # This is loaded before models/
.../app/controllers/concerns .../app/models/concerns .../test/mailers/previews
In my attempt to clean up some of our code, I unwittingly created a difficult bug to spot. Here is some example code to see the issue in action:
Hopefully Ruby on Rails autoloading is clearer now. You can always read more and improve Ruby on Rails documentation here. If you have any questions or found errors, please comment here or contact me on twitter!
In Rails 5, autoloading is disabled by default.