I started upgrading my application from Rails 6.1.1 to 7.0.3. While doing this I also had to upgrade Devise from 4.7.3
to 4.8.1
.
With old setup everything worked fine. Now after upgrading I can't start none of the following:
- rails server
- rails console
- rspec specs
- rake rails:update
They all fail with the following error message:
/home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/activesupport-7.0.3/lib/active_support/inflector/methods.rb:280:in `constantize': uninitialized constant AccountMailer
Did you mean? ActionMailer (NameError)
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/activesupport-7.0.3/lib/active_support/core_ext/string/inflections.rb:74:in `constantize'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/devise-4.8.1/lib/devise.rb:320:in `get'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/devise-4.8.1/lib/devise.rb:343:in `mailer'
from /home/andres/apps/my_app/config/initializers/devise.rb:25:in `block in <main>'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/devise-4.8.1/lib/devise.rb:307:in `setup'
from /home/andres/apps/my_app/config/initializers/devise.rb:5:in `<main>'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:39:in `load'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:39:in `load'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/engine.rb:667:in `block in load_config_initializer'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/activesupport-7.0.3/lib/active_support/notifications.rb:208:in `instrument'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/engine.rb:666:in `load_config_initializer'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/engine.rb:620:in `block (2 levels) in <class:Engine>'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/engine.rb:619:in `each'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/engine.rb:619:in `block in <class:Engine>'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/initializable.rb:32:in `instance_exec'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/initializable.rb:32:in `run'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/initializable.rb:61:in `block in run_initializers'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:228:in `block in tsort_each'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:422:in `block (2 levels) in each_strongly_connected_component_from'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:431:in `each_strongly_connected_component_from'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:421:in `block in each_strongly_connected_component_from'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/initializable.rb:50:in `each'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/initializable.rb:50:in `tsort_each_child'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:415:in `call'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:415:in `each_strongly_connected_component_from'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:349:in `block in each_strongly_connected_component'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:347:in `each'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:347:in `call'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:347:in `each_strongly_connected_component'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:226:in `tsort_each'
from /home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:205:in `tsort_each'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/initializable.rb:60:in `run_initializers'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/railties-7.0.3/lib/rails/application.rb:372:in `initialize!'
from /home/andres/apps/my_app/config/environment.rb:7:in `<main>'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/zeitwerk-2.5.4/lib/zeitwerk/kernel.rb:35:in `require'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/spring-2.1.1/lib/spring/application.rb:106:in `preload'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/spring-2.1.1/lib/spring/application.rb:157:in `serve'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/spring-2.1.1/lib/spring/application.rb:145:in `block in run'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/spring-2.1.1/lib/spring/application.rb:139:in `loop'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/spring-2.1.1/lib/spring/application.rb:139:in `run'
from /home/andres/.rvm/gems/ruby-3.0.0@my_app/gems/spring-2.1.1/lib/spring/application/boot.rb:19:in `<top (required)>'
from <internal:/home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from <internal:/home/andres/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from -e:1:in `<main>'
Mailer files
I'm having the following mailer-folder structure:
app/mailers:
account_mailer.rb
application_mailer.rb
My account_mailer.rb has the following declaration:
# frozen_string_literal: true
# using SendGrid's Ruby Library
# https://github.com/sendgrid/sendgrid-ruby
require 'sendgrid-ruby'
class AccountMailer < Devise::Mailer
include SendGrid
default template_path: 'devise/mailer'
Based on that the constantize
method should be able to do all it needs to I understand (file names match the class name, files are present under correct folder structure).
Devise initialization with mailer
My custom AccountMailer
is initialized inside Devise initializer like this: config.mailer = 'AccountMailer'
.
As I said- this all worked like a charm in Rails 6.1.1 but now I can't get my head around what's wrong after the Rails upgrade.
What I've tried:
I commented out all the AccountMailer
references. After that I started getting errors about Devise::Mailer like this (in RSpec):
An error occurred while loading rails_helper.
Failure/Error: require File.expand_path('../config/environment', __dir__)
NameError:
uninitialized constant Devise::Mailer
Did you mean? Devise::Mailers
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/activesupport-7.0.3/lib/active_support/inflector/methods.rb:280:in `constantize'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/activesupport-7.0.3/lib/active_support/core_ext/string/inflections.rb:74:in `constantize'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/devise-4.8.1/lib/devise.rb:320:in `get'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/devise-4.8.1/lib/devise.rb:343:in `mailer'
# ./config/initializers/devise.rb:25:in `block in <main>'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/devise-4.8.1/lib/devise.rb:307:in `setup'
# ./config/initializers/devise.rb:5:in `<main>'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:39:in `load'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:39:in `load'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/engine.rb:667:in `block in load_config_initializer'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/activesupport-7.0.3/lib/active_support/notifications.rb:208:in `instrument'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/engine.rb:666:in `load_config_initializer'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/engine.rb:620:in `block (2 levels) in <class:Engine>'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/engine.rb:619:in `each'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/engine.rb:619:in `block in <class:Engine>'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/initializable.rb:32:in `instance_exec'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/initializable.rb:32:in `run'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/initializable.rb:61:in `block in run_initializers'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/initializable.rb:50:in `each'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/initializable.rb:50:in `tsort_each_child'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/initializable.rb:60:in `run_initializers'
# /home/andres/.rvm/gems/ruby-3.0.0@vaab/gems/railties-7.0.3/lib/rails/application.rb:372:in `initialize!'
# ./config/environment.rb:7:in `<top (required)>'
# ./spec/rails_helper.rb:8:in `require'
# ./spec/rails_helper.rb:8:in `<top (required)>'
When I commented out all the Devise mailer configuration lines in Devise initializer like this:
# config.mailer = 'AccountMailer'
# config.mailer.perform_deliveries = !Rails.env.test?
# config.mailer.raise_delivery_errors = true
Then only at that point my application seemed to work 100% as it needs to.
I checked the Devise changelog for releases after 4.7.3 that I was upgrading from and I didn't notice any relevant changes there.
I also checked Rails mailer related configuration changes between versions 6.1.1 and 7.0.3 from release notes and I again didn't notice anything that might affect.
The constantize
method that appears in error trace is described here: https://api.rubyonrails.org/classes/String.html#method-i-constantize
I'm taking the Rails upgrade tutorial as basis from here. What could be the issue here?