In the process of upgrading to Rails 6.1, I came across a new exception with poor coverage on Google:
The Rails guide to Autoloading & Reloading Constant will give plenty of blah-blah-blah about Zeitwerk and why the autoloading system needed to be changed from the classic as of Rails 6. The important detail is this: any constant that is referenced in the course of invoking the files from config/initializers
will be listed by the deprecation message unless it was ready to be referenced.
What does "ready to be referenced" mean? As you'll read below, it means that either the constant was explicitly required, or the code that calls the constant was wrapped in Rails.application.reloader.to_prepare do
In spite of being long on words, the comment is short on useful follow up actions. After 30 minutes of Googling, this was the best process I could determine in order to resolve this:
The easiest way I found to determine this was following the instructions suggested here, and to add pp caller_locations
to print the callers for the module that is being listed. For example, in the deprecation warning above, Rails mentions that CustomErrors
was autoloaded, so I add pp caller_locations
at the top of my custom_errors.rb
file to print in console the full callstack by which the constant is being invoked. Or, if you just want to see the location from your initializers directory where the constant is being referenced, you can add this in front of the constant:
Once we have the callstack that is invoking the constant, then we can choose how to remedy it.
require
the constant or wrap itIn the case of CustomErrors
, looking at the callstack indicated that it was being referenced by config/initializers/devise.rb
. Thus, easiest way to fix the warning is by adding require "custom_errors"
to the top of config/initializers/devise.rb
If for some reason you aren't able or don't want to require the module's file, the other option is to wrap the caller in the incantation provided in Rails' deprecation message. In the case of the devise initializer, it would look something like
Which will reference the constant in question in a way that is reload-safe, thus removing the deprecation message.