The Rails 6+ default autoloader is zeitwerk, which seems like a great improvement over previous approaches.
However, zeitwork follows the convention for Rails projects that anything in
app/* is autoloaded and doesn't need to be namespaced.
This works great for
app/models/user.rb because you don't have to use
Models::User but can just reference
However, I added my own
app/services directory and I namespace my service objects as
Services::Users::Create, which would map to
Zeitwork is throwing errors that my class constants don't exist, since it is expecting
Users::Create (without the
Is there anyway to configure zeitwork to require the
Services:: namespace in these instances? In my opinion, it is a much cleaner to read the code as
Services::Users::Create and know that you're looking in the
If you just had
Users::Create, an average Rails developer would probably look for the
I don't like the approach of naming it
Users::CreateService, it just seems very inelegant to me.
I can't be the only one who uses conventions like this; has anyone else come across a solution? I'm still going through all the zeitwerk documentation looking for a solution but haven't found one yet.
Some projects want something like app/api/base.rb to define API::Base, and add app to the autoload paths to accomplish that in classic mode. Since Rails adds all subdirectories of app to the autoload paths automatically, we have another situation in which there are nested root directories, so that setup no longer works. Similar principle we explained above with concerns.
If you want to keep that structure, you'll need to delete the subdirectory from the autoload paths in an initializer: