So have a rails 5 project and would like to load a directory like this
/app
/services
/user
foo.rb
as the constant ::Services::User::Foo
Does anyone have experience in getting rails autoload paths to load the constants in this manner?
foo.rb
module Services
module User
class Foo
end
end
end
SOLUTION
Add this to your application.rb file
config.autoload_paths << Rails.root.join('app')
See discussions here on autoloading
https://github.com/rails/rails/issues/14382#issuecomment-37763348 https://github.com/trailblazer/trailblazer/issues/89#issuecomment-149367035
Rails automatically reloads classes and modules if application files in the autoload paths change. More precisely, if the web server is running and application files have been modified, Rails unloads all autoloaded constants managed by the main autoloader just before the next request is processed.
The Module#autoload method registers a file path to be loaded the first time that a specified module or class is accessed in the namespace of the calling module or class.
Modules are a way of grouping together methods, classes, and constants. Modules give you two major benefits. Modules provide a namespace and prevent name clashes. Modules implement the mixin facility.
You need to define Services::User::Foo
inside app/services/services/user/foo.rb
If you don't want this weird subfolder duplication, you could also move services
to app/models/services
or lib/services
.
You could also leave foo.rb
in app/services/user/foo.rb
, but it should define User::Foo
.
If you don't need any magic with namespaces and class names, it is pretty straightforward :
Dir[Rails.root.join('app/services/**/*.rb')].each{|rb| require rb}
This will eagerly load any Ruby script inside app/services
and any subfolder.
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