I'm upgrading my Rails app from v5 to v6. The files are structured as:
lib
|- container
|- my_module_a
| |- my_class.rb
| |- class_two.rb
|- my_module_b
my_module directory has no files in it, only my_module_a and my_module_b directories.
class_one.rb contents:
module MyModuleA
class MyClass
# definitions...
end
end
config/application.rb has:
config.eager_load_paths += %W[
#{config.root}/lib/container
#{config.root}/lib/container/my_module_a
]
bin/rails zeitwerk:check prints All is good!
However, when running the rails server and it reaches the call of the MyClass class
obj = Container::MyModule::MyClass.new(...)
it prints
uninitialized constant Container::MyModuleA
If you want to call
Container::MyModuleA::MyClassA, the class definition should be:Your current directory structure and the class definition are different
container/my_module_a/my_classvsMyModuleA::MyClass, the best practice is to prefix your classes with a module name that matches the directory tree. In development rails is disabling eager loading meaning that code is loaded on the fly (to reduce booting time) and when you callContainer::MyModuleA::MyClassA, it will lookup for thecontainer/my_module_a/my_class_afile, check the content to findContainer::MyModuleA::MyClassAwhich is not defined right now are the class definition is not nested in theContainermodule.More information about autoloading vs eager loading here: https://www.bigbinary.com/books/learn-rubyonrails-book/loading-behavior-of-ruby-on-rails-in-depth