Я обновляю свое приложение Rails с 6.1 до 7.0 и сталкиваюсь с этой ошибкой времени выполнения:
Я использую драгоценный камень Authlogic, но странно то, что у меня нет файла config/initializers
для Authlogic, и я не могу найти ни одного экземпляра константы, с которой он не работает.
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
ОБНОВЛЕНИЕ: После решения вышеуказанной проблемы (решение см. в комментарии @alex ниже), следующая связанная проблема Zeitwerk:
Следующим препятствием является то, что Zeitwerk не имеет одинаковых имен классов, даже если они находятся в разных пространствах имен, что и вызывает эту ошибку:
Exception Zeitwerk::NameError in Rack application object
(expected file app/services/data_tables/base.rb to define
constant Base, but didn't)
когда я включил ведение журнала Zeitwerk и запустил приложение, я увидел это:
[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
определяется как:
module Deployment
module Models
class Base < ActiveResource::Base
...
и app/services/data_tables/base.rb
это:
module DataTables
class Base
...
это то, что у меня есть в 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"
🤔 А знаете ли вы, что...
Одной из ключевых особенностей Rails является активная запись (Active Record) - ORM-система, которая упрощает взаимодействие с базой данных.
Добавление сводки исправлений, сделанных здесь, на случай, если это поможет другим. Спасибо @XavierNoria и @Alex за помощь.
Первоначальная причина заключалась в устаревшем файле исправления для Authlogic, названном так, как не понравилось Zeitwerk. В итоге я провел рефакторинг кода, чтобы полностью избавиться от файла, но если у вас есть файлы в lib/patches
, вам нужно будет заключить код в пространство имен Module Patches
.
Другая проблема заключалась в том, что в ряде классов Zeitwerk отказывался автоматически загружать классы с одинаковыми именами (хотя они явно находились внутри разных пространств имен/структур папок). Исправление заключалось в замене этой строки pre-rails-7.0 в config/application.rb
:
config.autoload_paths += Dir["#{config.root}/app/services/**/"]
с:
config.autoload_paths += Dir["#{config.root}/app/services"]
Это решило все проблемы конфликта имен классов.