Today I was making some improvements to a client's Rails codebase. This client has many services in the
services/ folder of the Rails application, and a handful of them are related to a specific purpose. I wanted to put these services in their own folder so I can easily find them while I'm workig.
I created a new folder under
services/ and tried to run the services the way I had been before, but it didn't work. I got an error about
Uninitialized contant MyServiceName.
I read about autoloading in the Rails Guides and learned that by default, a Rails app makes all the code that's a direct child of any of the folders that are present when you bootstrap a new app available to any other code. So, code in
services/service1.rb can see code in
services/service_helper.rb without any configuration, and both can be ran from my Rails console. (
When I moved code into a subfolder of
services/, it's no longer a direct child of that folder and so doesn't get autoloaded. I can change that by adding subfolders of any folder that's there by default to the autoload paths in
config.autoload_paths += Dir[Rails.root.join('app', 'services', '**/')]
After I added this line to the config, I had to exit my Rails console instance and re-enter it for my changes to take effect -
reload! didn't pick up the config file changes.
But once I restarted my console, I was able to run my service without
requireing anything special once more.
# Update 4-19-22
A coworker shared with me that if you namespace all your code in the subfolder using the name of the subfolder, you don't have to change the autoload paths and the code will get picked up automatically.
To namespace, either wrap everything in
module FolderNameInCamelCase, or prefix your class names with