Summary
On Rails edge (the unreleased rails/rails main branch), every boot of an app using devise_invitable emits two WARN -- : ... was loaded before application initialization log blocks:
:action_mailer was loaded before application initialization
:active_job was loaded before application initialization
These come from Rails' new guard_load_hooks support (rails/rails#56201), which logs when a framework load hook fires before the app has finished initializing.
Root cause
The Engine defined in lib/devise_invitable/rails.rb uses config.to_prepare to include DeviseInvitable::Mailer into Devise.mailer:
config.to_prepare do
Devise.mailer.send :include, DeviseInvitable::Mailer
unless Devise.mailer.ancestors.include?(Devise::Mailers::Helpers)
Devise.mailer.send :include, Devise::Mailers::Helpers
end
end
config.to_prepare blocks fire during the Rails finisher initializer (before Rails.application.initialized? flips to true). Inside the block, Devise.mailer does a String#constantize on the configured mailer class name (default "Devise::Mailer"), which loads the mailer class. The mailer class extends ActionMailer::Base, and ActionMailer::Base's class body includes ActionMailer::QueuedDelivery, which requires action_mailer/mail_delivery_job, which extends ActiveJob::Base. Result: both :action_mailer and :active_job run_load_hooks fire during boot.
Example boot log
WARN -- : :action_mailer was loaded before application initialization.
Prematurely executing load hooks will slow down your boot time
and could cause conflicts with the load order of your application.
Please wrap your code with an on_load hook:
ActiveSupport.on_load(:action_mailer) do
# your code here
end
Called from:
...
/devise_invitable-2.0.9/lib/devise_invitable/rails.rb:12:in 'block in <class:Engine>'
...
(Same shape for :active_job, via ActionMailer::Base → MailDeliveryJob.)
Proposed fix
Wrap the body of the to_prepare block in ActiveSupport.on_load(:action_mailer):
config.to_prepare do
ActiveSupport.on_load(:action_mailer) do
Devise.mailer.send :include, DeviseInvitable::Mailer
unless Devise.mailer.ancestors.include?(Devise::Mailers::Helpers)
Devise.mailer.send :include, Devise::Mailers::Helpers
end
end
end
The reload semantics noted in the existing comment are preserved: on every to_prepare cycle a fresh on_load(:action_mailer) block is registered, and since :action_mailer has fired by then on subsequent reloads it runs immediately. The first boot defers it until ActionMailer is actually loaded — past app initialization, so no warning.
I've opened a PR with this change against master: TBD-link.
Versions
- Reproduces on
devise_invitable v2.0.12 (latest as of writing).
- Rails: the
rails/rails main branch any time after rails/rails#56201 merged.
- Stable Rails users won't see the warnings until Rails 8.2 (or whichever stable release ships
guard_load_hooks).
Happy to add a regression test if helpful — wasn't sure how the existing test harness exercises railtie load order, so kept the PR minimal.
Summary
On Rails edge (the unreleased
rails/railsmain branch), every boot of an app usingdevise_invitableemits twoWARN -- : ... was loaded before application initializationlog blocks::action_mailerwas loaded before application initialization:active_jobwas loaded before application initializationThese come from Rails' new guard_load_hooks support (rails/rails#56201), which logs when a framework load hook fires before the app has finished initializing.
Root cause
The
Enginedefined inlib/devise_invitable/rails.rbusesconfig.to_prepareto includeDeviseInvitable::MailerintoDevise.mailer:config.to_prepareblocks fire during the Railsfinisherinitializer (beforeRails.application.initialized?flips totrue). Inside the block,Devise.mailerdoes aString#constantizeon the configured mailer class name (default"Devise::Mailer"), which loads the mailer class. The mailer class extendsActionMailer::Base, andActionMailer::Base's class body includesActionMailer::QueuedDelivery, whichrequiresaction_mailer/mail_delivery_job, which extendsActiveJob::Base. Result: both:action_mailerand:active_jobrun_load_hooksfire during boot.Example boot log
(Same shape for
:active_job, viaActionMailer::Base→MailDeliveryJob.)Proposed fix
Wrap the body of the
to_prepareblock inActiveSupport.on_load(:action_mailer):The reload semantics noted in the existing comment are preserved: on every
to_preparecycle a freshon_load(:action_mailer)block is registered, and since:action_mailerhas fired by then on subsequent reloads it runs immediately. The first boot defers it until ActionMailer is actually loaded — past app initialization, so no warning.I've opened a PR with this change against
master: TBD-link.Versions
devise_invitablev2.0.12 (latest as of writing).rails/railsmainbranch any time after rails/rails#56201 merged.guard_load_hooks).Happy to add a regression test if helpful — wasn't sure how the existing test harness exercises railtie load order, so kept the PR minimal.