How can I preload concerns in a rails initializer using Rails 6/Zeitwerk?
As described by @Glyoko's answer, using require
on dependencies prevents autoloading in initializers. However, doing so leads to problems during reloading as @Puhlze mentioned in his comment.
I stumbled across an alternate approach that utilizes Rails.configuration.to_prepare
in this post.
An example would be:
# config/initializers/my_initializer.rb
Rails.configuration.to_prepare do
class SomeExternalLib
include MyConcern1
include MyConcern2
end
end
Note that this runs before every request in development but only once before eager loading in production.
Edit: it appears to also work with reloading.
How to properly extend ApplicationRecord in Rails 6 with Zeitwerk
Figured it out! The issue was there was an explicit require in an initializer that loaded ApplicationRecord.
# config/initializers/setup_other_fancy_thing.rb
require 'application_record'
module OtherFancyThing
def also_fancy
puts 'also fancy'
end
end
ApplicationRecord.send(:include, OtherFancyThing)
The way I debugged this was that I:
- Created a new Rails app of the same version and could not reproduce the error
- I copied the default application.rb and development.rb and still got the error
- Moved the entire
config/initializers
directory to a temp directory and it made the warning go away! So, I knew it had to be one of the initializers. From there it was just a matter of dividing and conquering until I found the offending initializer.
Rails 6 Zeitwerk DEPRECATION WARNING: Initialization autoloaded the constants... but I can't figure out where?
Turns out this seems to be related to rails_admin
.
How I learned this:
Someone else shared my frustration at the warning message and asked for more help tracing the issue.
One response recommended putting pp caller_locations
at the top of one of the files that was being autoloaded. Doing this gave me a traceback I could use. That's when I noticed that rails_admin
appeared as a path in each one.
I noticed I already had a huge list of require
statements in config/initializers/rails_admin.rb
:
require 'money-rails/rails_admin'
require 'rails_admin/adapters/active_record'
require 'application_record'
require 'user'
require 'event'
require 'registration'
require 'location'
require 'technology'
require 'supplier'
require 'component'
require 'part'
require 'material'
require 'count'
require 'inventory'
require 'extrapolate_component_part'
require 'extrapolate_material_part'
require 'extrapolate_technology_component'
require 'extrapolate_technology_part'
require 'extrapolate_technology_material'
For a lark, I commented all of them out, then ran a RSpec test. My warning message suddenly got SUPER long with a bunch more instances:
DEPRECATION WARNING: Initialization autoloaded the constants ApplicationHelper, EventsHelper, FontAwesome::Rails::IconHelper, DeviseHelper, ErrorHandler, ApplicationController, ApplicationRecord, User, Event, Registration, Location, Technology, Component, Part, Material, Supplier, Count, Inventory, ExtrapolateComponentPart, ExtrapolateMaterialPart, ExtrapolateTechnologyComponent, ExtrapolateTechnologyPart, and ExtrapolateTechnologyMaterial.
So I decided to add in my previous instances:
require 'application_helper'
require 'events_helper'
require 'devise_helper'
require 'error_handler'
require 'application_controller'
...to my already long list, my warning message, all of them but the FontAwesome::Rails::IconHelper
goes away. I think I can get that one too, if I can just figure out the correct filepath.
DEPRECATION WARNING: Initialization autoloaded the constants ActionText::ContentHelper and ActionText::TagHelper
A bit of sleuthing revealed two sources of this deprecation warning in my Rails 6.1 app.
I referenced ActionMailer::Base in a couple of initializers. Based on the suggestion in the Rails Guides (https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration), I decided to move all those references to environment.rb.
The same deprecation error was also apparently being generated by the mailgun-ruby gem v 1.2.3. It appears the deprecation warning has been fixed in v 1.2.4.
Related Topics
Testing Routes with Subdomain Constraints Using Rspec
How to Get a Selenium/Ruby Bot to Wait Before Performing an Action
What Is the Purpose of 'Kernel'
Changing Songs on Jplayer by Clicking a Link, Hosted on Amazon S3
Storing Passwords for External APIs - Best Practice
Remove Subdomain from String in Ruby
How to Split a String by Commas Except Inside Parenthesis, Using a Regular Expression
How to Model a Mutual Friendship in Rails
Select Checkbox Pass Array in Ruby on Rails
How Do Version Numbers Work for Mri Ruby
How to Count Existing Instances of a Class in Ruby
Unpermitted Parameters for Dynamic Forms in Rails 4
Simplest Way to Send Raw Byte-Arrays Using Ruby's Tcpsocket-Class
Stop Loading Page Watir-Webdriver