Rails 6 未在开发中正确自动加载 class(zeitwerk 模式)

Rails 6 not auto-loading class properly in development (zeitwerk mode)

我的理解是 Rails 能够在默认情况下自动加载 app 文件夹中正确命名的 类。

我没有遇到这种情况,所以我想看看您是否能找到我的代码中的一个明显问题。

我的folders/files:

app
   blueprints
      concerns
         ingredient_blueprint_concern.rb
      liqueur_blueprint.rb
   controllers
   models
   ...
#app/blueprints/concerns/ingredient_blueprint_concern.rb

module Concerns
  module IngredientBlueprintConcern
    extend ActiveSupport::Concern

    included do
      attributes :name
    end
  end
end

# app/blueprints/liqueur_blueprint.rb

class LiqueurBlueprint < BaseBlueprint
  include ::Concerns::IngredientBlueprintConcern

  # ...
end

rails 控制台:

> Concerns
=> NameError (uninitialized constant Concerns
   Did you mean?  Concurrent):

这似乎与新的 Rails 6 zeitwerk 模式有关。如果我回到 classic 模式(使用下面的代码),它似乎工作正常:

# application.rb
config.autoloader = :classic

https://github.com/rails/rails/issues/36054

好吧,原来 concerns 文件夹实际上在 rails 加载路径中,所以这意味着它们不应该命名空间,就像 class 是 [=11] =] 不在 Models 命名空间中。

他们在 Rails 5 中工作的事实是某种副作用,我不会在这里讨论,但您可以在上面的 link 中阅读。

我想知道我们是否可以得到关于这个问题的答案...

# app/foo/bar.rb

module Foo
  class Bar
    def output
      'worked'
    end
  end
end

irb(main):001:0> Foo
NameError (uninitialized constant Foo)

irb(main):002:0> Bar
Zeitwerk::NameError (expected file /Users/simon/Projects/tmp/test_module/app/foo/bar.rb to define constant Bar, but didn't)

irb(main):003:0> Foo
=> Foo

但是

irb(main):007:0> ActiveSupport::Dependencies.autoload_paths.include?("/Users/simon/Projects/tmp/test_module/app/foo")
=> true

如果我先调用 Bar 并在 Foo 之后调用 Bar 为什么它会起作用?自动加载问题?

编辑(2020 年 8 月 1 日)

将文件路径更改为 app/foo/foo/bar.rb 使其工作。现在对我来说是一个解决方法。