Rails autoload and eager load paths

Jan 28, 2015

How rails finds and loads classes when using autoload_paths and 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.

autoload_paths

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 foo/bar/baz.rb

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.

[4] 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

eager_load_paths are the way to immediately load constants at startup (assuming config.cache_classes is true, 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 eager_load_path.

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 autoload_paths or eager_load_paths.


Tags: