Я пытаюсь обновить свое приложение с Rails 5.2 до 6.1 и использовать автозагрузку Zeitwerk, и у меня возникают проблемы с автозагрузкой классов /lib
.
Я включил это в config/application.rb
:
config.load_defaults 5.2
config.autoloader = :zeitwerk
config.enable_dependency_loading = true
config.autoload_paths += Dir[Rails.root.join('lib/**/*')]
config.eager_load_paths += Dir[Rails.root.join('lib/**/*')]
И когда я запускаю zeitwerk:check
, он предупреждает меня, что:
Hold on, I am eager loading the application.
expected file lib/facades/coconut/v2/foo.rb to define constant Foo
Он объявлен как:
# /lib/facades/coconut/v2/foo.rb
module Coconut
module V2
class Foo
# ...
end
end
end
Когда я пытаюсь его отладить (ставя binding.pry
в каком-то тестовом файле), Zeitwerk говорит, что он не определен, пока я не вызову его без модулей (пространств имен):
[1] pry(#<#filename>)> Coconut::V2::Foo
NameError: uninitialized constant Coconut::V2::Foo
from (pry):1:in `setup`
[2] pry(#<#filename>)> Foo
Zeitwerk::NameError: expected file /my-app/lib/api/coconut/v2/foo.rb to define constant Foo, but didn't
from /usr/local/bundle/gems/zeitwerk-2.5.4/lib/zeitwerk/loader/callbacks.rb:25:in `on_file_autoloaded'
[3] pry(#<#filename>)> Coconut::V2::Foo
=> Coconut::V2::Foo
Звучит очень странно, потому что в /lib
есть другие классы с той же структурой, но они работают хорошо, например
# /lib/api/services/youtube/client.rb
module Services
module Youtube
class Client
# ...
end
end
end
Проверка его с помощью binding.pry
в каком-то тесте:
pry(#<#filename>)> Services::Youtube::Client
=> Services::Youtube::Client
Кто-нибудь имел эту проблему или знает, что может произойти?
Система:
Путь автозагрузки — это корневой каталог, а не его содержимое.
Вам нужно удалить подстановочные знаки, как задокументировано здесь.