How rails finds and loads classes when using
eager_load_paths can be pretty confusing. This post is the best that I’ve read on the topic, but there are a few things that I think are worth explaining more.
This helps rails locate where an unknown constant is defined. So if it encounters the constant
Foo::Bar::Baz, it knows to look for it in
That is why you only need to add
lib/, instead of
lib/**/*, to the paths. If you had
lib/foo/bar in your autoload path then it would expect
Foo::Bar::Baz to be in
lib/foo/bar/foo/bar/baz.rb. You can check out the current autoload paths using
ActiveSupport::Dependencies.autoload_paths in the rails console.
 pry(main)> ActiveSupport::Dependencies.autoload_paths => ["<path_to>/app/assets", "<path_to>/app/controllers", "<path_to>/app/datatables", "<path_to>/app/decorators", ...
eager_load_paths are the way to immediately load constants at startup (assuming
config.eager_load actually controls whether
eager_load_namespaces are eager loaded…).
The documentation is somewhat ambiguous as to whether this should be exhaustive like
lib/**/* or whether each path in
eager_load_paths is searched recursively. We can look at the railties source and verify that it does indeed recursively load sub directories of each
This is consistent with the behavior described in the above post. Including
/lib will make everything work, but the downside is that things like our rake tasks and other non-web-serving constants will be unnecessarily loaded into memory.
Hope this helps others work through what all rails is doing when you set