Есть ли программный способ обнаружить Zeitwerk::NameError при обновлении до Rails 6?

В настоящее время я переношу старое приложение Rails на Rails 6.

Похоже, что некоторые файлы в проекте не соответствуют определенным в нем классам. Я не вижу этой ошибки при запуске тестов приложения, но после развертывания я получаю такие ошибки, как:

        Zeitwerk::NameError: expected file /app/my?_/app/lib/multi_io.rb to define constant MultiIo, but didn't

В предыдущих вопросах SO я мог найти предложения:

Я не ищу обходного пути, поэтому исправил файл, вызывающий исключение.

Я хотел бы найти программный способ обнаружения всех несовместимых имен путей / классов без запуска приложения в производственном режиме.

Пока мне в голову пришло три варианта:

  1. Задача rake для проверки автозагрузки (которая не предоставляется гемом). Он существует? Не могли бы вы вместо этого запускать фрагмент из консоли rails в среде разработки?
  2. Рубокоп или другой статический анализатор кода. Существует какой-либо?
  3. Заставить нетерпеливую нагрузку в тестовой среде

Что это за предлагаемый подход к проверке моего кода без необходимости нескольких итераций / развертываний?

заранее большое спасибо

2 ответа

Решение

Вы можете проверить совместимость автозагрузки проекта с помощью zeitwerk::check задача:

$ bin/rails zeitwerk:check
Hold on, I am eager loading the application.
All is good!

Он выполняет все пути автозагрузки и помечает проблемы, например, вызванные изменением вывода имени константы (например, с акронимами). Задача не широко рекламируется или не документируется, за исключением руководства по обновлению. Но на самом деле я иногда использую его, чтобы просто избавиться от постоянных проблем с именованием в проекте в целом (то есть, когда класс не соответствует файлу).

@rmlockerd описал один из лучших инструментов для этого в своем ответе здесь .

Другие статьи, которые я нашел информативными, были:

Процесс, который я взял, состоял в том, чтобы запустить bin/rails zeitwerk:checkисправь ошибку, запусти еще раз, пока не увидишь "Все хорошо". После этого проработали ошибки, о которых сообщают наши тесты спецификации.

Одна общая проблема, которую необходимо исправить, заключается в том, что если папка не находится в файловой структуре Rails по умолчанию, Zeitwerk не сможет найти ее при автозагрузке. У нас была папка с именем «services» ( app/services), который необходимо добавить в путь автозагрузки в файле application.rb, например:

      config.autoload_paths += %W(#{config.root}/app/services/)

Ошибка:

Ожидаемый файл path/file_name.rbопределить константу FileName

Документ Rails по автозагрузкеИсправить: удалить любой requireили же require_relativeв других файлах, ссылающихся на определение класса (Zeitwerk в них не нуждается).

Ошибка (класс определен в модуле подкаталога):

NameError: неинициализированная константа SubFile::ClassName

Исправить:

Подробно в другом ответе S/O. Всякий раз, когда метод используется в подпапках, структурируйте вызов как Folder::SubDirectory::Class.method_call

Удачи!

Другие вопросы по тегам