【问题标题】:Classes with the same name results in uninitialized constant when using Rails 6 Zeitwerk使用 Rails 6 Zeitwerk 时,具有相同名称的类会导致未初始化的常量
【发布时间】:2020-10-15 22:44:57
【问题描述】:

我遇到了zeitwerk 的问题,我无法访问另一个同名的模型常量。例如:

/app/models 我有一个worker.rb 文件,其中有一个常量RETRY_COUNT

class Worker < ApplicationRecord
  RETRY_COUNT = 10
end

/lib 中,我有一个/critical/worker.rb 文件,但在critical 下命名

module Critical
  class Worker
    some_method(::Worker::RETRY_COUNT)
  end
end

我可以使用::Worker 调用工作模型类,但是当我调用::RETRY_COUNT 时,会导致

NameError: uninitialized constant Worker (call 'Worker.connection' to establish a connection)::RETRY_COUNT

无论如何?我可以在Critical::Worker 类上硬编码RETRY_COUNT,但我想避免这样做。

【问题讨论】:

  • ::Worker.const_get(:RETRY_COUNT) 可能有帮助吗?
  • @JoshBrody 没用。任何获得常量的方法都会导致相同的错误
  • 我尝试过的替代方案stackoverflow.com/a/33489452/4852449

标签: ruby-on-rails ruby ruby-on-rails-6 zeitwerk


【解决方案1】:

根据您的更新,我相当肯定您有循环依赖。 has_many 调用在“ApplicationRecord 初始化”期间处理。在“AR 初始化”期间,其中一个在 has_many 中引用了 Critical::Worker.foo,它为 RETRY_COUNT 引用了 ::Worker(一个 AR),尚未完成初始化。

如果“AR 初始化时间”需要此值,则将其放入没有其他依赖项的文件中。

module Independent # no other dependencies in this file
  RETRY_COUNT = 10
end

然后:

class Worker < ApplicationRecord
  RETRY_COUNT = Independent::RETRY_COUNT
end

module Critical
  class Worker
    RETRY_COUNT = Independent::RETRY_COUNT
  end
end

Zeitgeist 应该能够确定它需要先加载 Independent,然后再加载其他任何内容,例如您的 AR 类。

【讨论】:

  • 不幸的是,这些都不起作用。第一个导致uninitialized constant #&lt;Class:0x00007fa7a0097be0&gt;:: RETRY_COUNT ,第二个导致undefined method retry_count' for Critical::Worker:Class (NoMethodError)
  • 我可能应该提到 RETRY_COUNT 在类中的方法中被调用(如has_many),请参阅编辑后的帖子
  • 哦,我想我明白发生了什么。用新信息更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 2015-05-03
  • 2016-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多