【问题标题】:NameError: uninitialized constant #<Class:0x00007fadd32ea580>::SearchableNameError: 未初始化的常量#<Class:0x00007fadd32ea580>::Searchable
【发布时间】:2020-06-03 23:59:50
【问题描述】:

在 rspec 中调试一个不相关的问题时,我遇到了持续加载的问题。 设置如下:

# app/models/foo.rb

class Foo << ApplicationRecord
  include Foo::Searchable
end
# app/models/foo/searchable.rb

module Foo::Searchable
  extend ActiveSupport::Concern

  included do
    #yada yada
  end
end

我在调试时收到以下错误。 NameError: uninitialized constant #&lt;Class:0x00007fadd32ea580&gt;::Searchable 将命名更改为 Foos::Searchable 并使用相应的文件夹移动确实可以解决问题,但我想了解实际发生的情况。

Rails 6.0.3.1 Ruby 2.6.6

【问题讨论】:

    标签: ruby uninitialized-constant


    【解决方案1】:

    除了使用&lt;&lt; 而不是&lt; 之外,由于误用范围解析运算符::,您已经成为真正常见问题的受害者。声明嵌套类或模块时不应使用它,因为它会导致错误的模块嵌套并导致缺少常量错误,除非您嵌套的模块已加载。

    You should always explitly declare nested modules/classes:

    class Foo < ApplicationRecord
      module Searchable
        extend ActiveSupport::Concern
        included do
          #yada yada
        end
      end
    end
    

    在过渡到 Rails 6 后,这个问题到处出现的原因是旧的经典自动加载器重载了 Module#const_missing 并掩盖了这些错误,因为它会自动加载 Foo。

    Zeitwork 取代了经典的自动加载器,而是使用 Module#autoload,这是 Ruby 的一个相对较新的补充,而且不那么 hacky。

    【讨论】:

      【解决方案2】:

      这是由于与 Byebug 不兼容造成的。 Byebug 在调试会话中停止 Zeitwerk 用于自动加载的事件。问题描述为here

      &lt;&lt; 是一个错字,不会导致该错误。

      【讨论】:

        【解决方案3】:

        也许你应该用

        class Foo < ApplicationRecord
          include Foo::Searchable
        end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-01-19
          • 2015-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-04
          • 2016-06-12
          相关资源
          最近更新 更多