I'm upgrading my rails app from 6.1 to 7.0 and i'm running into this runtime error:
I do use the Authlogic gem, but the odd thing is i have no config/initializers
file for Authlogic, and i can't find any instance of the constant that it's failing on.
uninitialized constant Patches::AuthlogicPasswordPatch (NameError)
/myapproot/shared/bundle/ruby/3.3.0/gems/zeitwerk-2.6.16/lib/zeitwerk/cref.rb:91:in `const_get'
/myapproot/shared/bundle/ruby/3.3.0/gems/zeitwerk-2.6.16/lib/zeitwerk/cref.rb:91:in get
UPDATE: After resolving the above issue (see the comment from @alex below for the solution), the next related Zeitwerk issue is:
the next blocker is that Zeitwerk isn't similarly named classes even though they are in different namespaces, which causes this error:
Exception Zeitwerk::NameError in Rack application object
(expected file app/services/data_tables/base.rb to define
constant Base, but didn't)
when i enabled logging for Zeitwerk and start the app, i see this:
[email protected]: file app/services/deployment/models/base.rb is ignored because app/services/data_tables/base.rb has precedence
app/services/deployment/models/base.rb
is defined as:
module Deployment
module Models
class Base < ActiveResource::Base
...
and app/services/data_tables/base.rb
is:
module DataTables
class Base
...
his is what i have in the config/application.rb:
config.autoload_paths += Dir["#{config.root}/app/services/**/"]
config.eager_load_paths << "#{Rails.root}/lib"
config.eager_load_paths << "#{Rails.root}/app/services"
Adding a summary of fixes done here in case it helps others. Thanks to @XavierNoria and @Alex for their help.
The initial cause was an outdated patch file for Authlogic that was named in a way that Zeitwerk did not like. I ended up refactoring the code to get rid of the file entirely, but if you have files in lib/patches
then you will need to enclose the code inside a Module Patches
namespace.
The other issue was that there were a number of classes where Zeitwerk was refusing to autoload classes that were named the same (even though they were clearly inside different namespaces / folder structures). The fix here was to replace this pre-rails-7.0 line in config/application.rb
:
config.autoload_paths += Dir["#{config.root}/app/services/**/"]
with:
config.autoload_paths += Dir["#{config.root}/app/services"]
This resolved all the class-name collission issues.