How to Preload Concerns in a Rails Initializer Using Rails 6/Zeitwerk

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:

  1. Created a new Rails app of the same version and could not reproduce the error
  2. I copied the default application.rb and development.rb and still got the error
  3. 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.

  1. 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.

  2. 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



Leave a reply



Submit