Обновляю приложение с 6.1 на 7.0, Ruby 3.1.2. В 6.1 у нас ещё стоял config.autoloader = :classic, в 7.0 его убрали, и теперь при первом обращении к клиенту падает:
Zeitwerk::NameError: expected file /app/app/services/api_client.rb to define constant ApiClient, but didn't
.../zeitwerk-2.6.0/lib/zeitwerk/loader/callbacks.rb:25:in `on_file_autoloaded'
.../app/controllers/orders_controller.rb:12:in `sync'
В файле при этом лежит class APIClient, и так было года три. Ещё есть папка lib/payments, которую раньше подгружали через autoload_paths. Переименовывать класс страшно, он используется мест в сорока. Как правильно?
Самая частая история при переходе на Zeitwerk. Classic искал файл по имени константы, которую ты запросил, а Zeitwerk идёт наоборот: смотрит на имя файла и ждёт, что api_client.rb определит ApiClient. Переименовывать ничего не нужно, достаточно подсказать инфлектору:
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym "API"
end
Только acronym действует на всё приложение: какой-нибудь ApiController в другом месте тоже начнёт ожидаться как APIController. Если такое есть, можно точечно, только для автозагрузчика:
# config/initializers/zeitwerk.rb
Rails.autoloaders.each do |autoloader|
autoloader.inflector.inflect("api_client" => "APIClient")
end
Потом прогони bin/rails zeitwerk:check: он загрузит всё разом и покажет оставшиеся несовпадения списком. По одному чинить быстрее, чем ловить их на проде. Про lib: в 7.0 добавь её в autoload_paths и eager_load_paths, а lib/tasks и lib/assets убери через Rails.autoloaders.main.ignore, иначе Zeitwerk полезет в rake-файлы.
zeitwerk:check очень выручает. Мне он когда-то нашёл файл, где лежали два класса сразу, при classic это годами работало
Спасибо, заработало. Сделала через inflector.inflect только для api_client, глобальный acronym сломал бы ApiController в админке. zeitwerk:check нашёл ещё три файла: в lib/payments/errors.rb жили четыре класса ошибок, разнесла по отдельным файлам. Тесты зелёные, завтра на стейдж.