Home > Blockchain >  Zeitwerk doesn't requires lib classes properly in Rails 6.1.6
Zeitwerk doesn't requires lib classes properly in Rails 6.1.6

Time:05-18

I'm trying to update my app from Rails 5.2 to 6.1, and use Zeitwerk autoload, and I am having some issues for autoloading /lib classes.

I included this in 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/**/*')]

And, when I run zeitwerk:check, it alerts me that:

Hold on, I am eager loading the application.
expected file lib/facades/coconut/v2/foo.rb to define constant Foo

It is declared as:

# /lib/facades/coconut/v2/foo.rb

module Coconut
  module V2
    class Foo
      # ...
    end
  end
end

When I try to debug it (putting a binding.pry in some test file), Zeitwerk says it do not defined, until I call it without modules (namespaces):

[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

It sounds really strange, because there are another classes in /lib that follows the same structure, but it works well, example

# /lib/api/services/youtube/client.rb

module Services
  module Youtube
    class Client
      # ...
    end
  end
end

Inspecting it with binding.pry in some test:

pry(#<#filename>)> Services::Youtube::Client
=> Services::Youtube::Client

Has anyone had this problem or know what could be happening?

System:

  • ruby 2.7.6p219
  • Rails 6.1.6
  • Zeitwerk (2.5.4)

CodePudding user response:

An autoload path is a root directory, not its contents.

You need to remove the wildcards as documented here.

  • Related