Starting with Rails 6, Rails shipped with a new
and better way to autoload,
which delegates loading to the
Zeitwerk gem.
This is the zeitwerk
mode.
Before Rails 7, it was still possible to switch back to the classic
mode
which used an autoloader implemented in Active Support.
Rails now does not include this autoloader anymore.
Unfortunately, not all native Rails modules have been moved to the Zeitwerk yet.
Before
The classic autoloader has been extremely useful,
but had several issues that made autoloading a bit tricky
and confusing at times.
At a high level,
the classic mode loads files
by looking them up on Module.nesting
and Module.ancestors
.
This was a traversal, therefore, the first match would be loaded.
While this works fine most of the time the classic mode ran into some obscure failures.
Zeitwerk takes an entirely different approach
in auto-loading by registering constants to be autoloaded instead.
This removes the dependency load order.
Let’s look at a quick example,
In the classic mode,
if Admin::UserManager
was loaded
before Admin::User
,
then calling User.all
would load from User
instead of Admin::User
.
However with Zeitwerk,
Rails will call Zeitwek#setup
.
This method takes care of setting up the autoloaders
for all of the known autoload_paths
.
The above example will look something like this,
Back to ActionCable! Prior to this change,
one had to specifically autoload all dependencies
of ActionCable so as to not run into any const_missing
error callbacks.
After
Thanks to this PR, much of this ‘bureaucratic’ code can now be removed!