Consider a Rails 6 application that has app/models/application_record.rb. This Rails 6 application is using Zeitwerk loader.
class ApplicationRecord
end
If I want to add functionality to ApplicationRecord via a module:
# app/models/concerns/fancy_methods.rb
module FancyMethods
def fancy_pants
puts "I'm wearing fancy pants"
end
end
and do the following:
class ApplicationRecord
include FancyMethods
end
I will get a deprecation warning or error:
DEPRECATION WARNING: Initialization autoloaded the constant FancyMethods.
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 FancyMethods, for example,
the expected changes wont be reflected in that stale Module object.
This autoloaded constant has been unloaded.
Please, check the "Autoloading and Reloading Constants" guide for solutions.
(called from <top (required)> at /Users/peter/work/recognize/config/environment.rb:5)
I've read lots of articles including the Rails autoload docs, but nothing really addresses this minimal but common case of extending ApplicationRecord. Yes, I could wrap ApplicationRecord in a .to_prepare block like:
Rails.configuration.to_prepare do
class ApplicationRecord < ActiveRecord::Base
include FancyMethods
end
end
But this seems like a code smell and could cause other unexpected problems now or down the line.