Неверно сказать, что Zeitwerk устраняет «необходимость в пространстве имен». Zeitwerk действительно автоматически загружает все подкаталоги app
(кроме assets
, javascripts
и views
). Все каталоги под app
загружаются в пространство имен 'root'. Но Zeitwerk также «автоматически оживляет» модули для любых каталогов, находящихся в этих корнях. Итак:
/models/foo.rb => Foo
/services/bar.rb => Bar
/services/registration/add_demo_data.rb => Registration::AddDemoData
Если вы уже привыкли загружать константы из «нестандартных» каталогов (путем добавления в config.autoload_paths
), обычно не так много изменений. Тем не менее, есть несколько случаев, которые требуют небольшой настройки. Первый - это когда вы переносите проект, который просто добавляет app
в путь автозагрузки. В classi c (до Rails 6) это позволяет вам использовать app/api/base.rb
, чтобы содержать API::Base
, тогда как в Zeitwerk ожидается, что он будет содержать только Base
. Это тот случай, о котором вы упомянули выше, когда рекомендуется исключить этот каталог из пути автозагрузки. Другой альтернативой было бы просто добавить каталог-оболочку, например app/api/api/base.rb
.
Вторая проблема, которую следует отметить, - это то, как Zeitwerk выводит константы из имен файлов. Из руководства по миграции Rails:
classic
режим выводит имена файлов из отсутствующих имен констант (подчеркивание), тогда как режим zeitwerk выводит имена констант из имен файлов (camelize). Эти помощники не всегда противоположны друг другу, особенно если используются акронимы. Например, "FOO".underscore
это "foo"
, но "foo".camelize
это "Foo"
, а не "FOO"
.
Итак, /api/api/base.rb
фактически соответствует Api::Base
в Zeitwerk, а не API::Base
.
Zeitwerk включает задачу rake для проверки автозагрузки в проекте:
% bin/rails Zeitwerk:check
Hold on, I am eager loading the application.
expected file app/api/base.rb to define constant Base