Today I Learned

Rails 6 introduces a new auto loader called zeitwork. The literature has me convinced transitioning to this new loader will be worth the effort. The legacy of the Rails apps we’ve built has us opting for the :classic loader in the immediate.

A nice thing about using :classic, is that Rails provides some deprecations that point toward getting ready for :zeitwork. As an example, autoloading constants in an initializer (config/initializers/[something].rb) emits a deprecation warning in Rails 6.

DEPRECATION WARNING: Initialization autoloaded the constants Sortable, Foldable, and Launderable.

Being able to do this is deprecated. Autoloading during initialization is going to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during initialization does not run again. So, if you reload Sortable, for example, the expected changes won't be reflected in that stale Class object.

`config.autoloader` is set to `classic`. These autoloaded constants would have been unloaded if `config.autoloader` had been set to `:zeitwerk`.

Please, check the "Autoloading and Reloading Constants" guide for solutions.

Following the Autoloading and Reloading Constants guide, and some supplementary Duck Duck Go’ing, I learned about the Rails.configuration.to_prepare API. Where initializers run once when the app is booting, blocks passed to to_prepare will be run before every request in development, and once before eager loading in production.

For a handful of constants that are being autoloaded in an initializer, using to_prepare did the trick.

-ActiveRecord::Base.send :include, Sortable
+Rails.configuration.to_prepare { ActiveRecord::Base.send :include, Sortable }