Skip to content

devise_for triggers premature load of Rails components during route drawing in production rake tasks #5847

Description

@yokonao

Summary

When running rake tasks with RAILS_ENV=production, devise_for triggers premature
loading of Rails components during route drawing, causing warnings introduced by a
recent Rails edge change that detects components loaded before application initialization.

Environment

  • Rails: edge (main branch), confirmed on 2460b23b38ad
  • Devise: 5.0.4

Steps to reproduce

rails new myapp --main
cd myapp

Add to Gemfile:

gem "devise"
bundle install
bin/rails generate devise:install
bin/rails generate devise Administrator
RAILS_ENV=production bin/rails db:prepare

Expected behavior

Completes without any warnings.

Actual behavior

The following warning is printed:

:active_model_secure_password 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(:active_model_secure_password) do
    # your code here
  end
Called from:
...
/devise/mapping.rb ...
/config/routes.rb ...

Estimated cause

Rails edge introduced a load hook guard mechanism (rails/rails#56201) that warns
when Rails components are loaded before the application is fully initialized.

When RAILS_ENV=production, routes are eager-loaded. devise_for :administrators
causes the Administrator model to be loaded via constantize during route drawing,
in order to determine which Devise modules are included (e.g. :registerable) and
thus which routes to generate. This triggers the new Rails warning as
ActiveModel::SecurePassword (and other components) are loaded before the
application is fully initialized.

This only reproduces under RAILS_ENV=production with a Rake task because
config.rake_eager_load defaults to false, overriding config.eager_load = true
at Rake task execution time — making the Rails load hook guard condition
(!Rails.configuration.eager_load) pass.

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions