Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Way to load folder as module constant in rails app directory

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

like image 576
Austio Avatar asked Dec 01 '16 21:12

Austio


People also ask

How does Rails load modules?

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.

What is autoload in Ruby?

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.

What are modules in Rails?

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.


1 Answers

Auto loading

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.

Eager loading

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.

like image 185
Eric Duminil Avatar answered Oct 10 '22 17:10

Eric Duminil