Классы с тем же именем приводят к неинициализированной константе при использовании Rails 6 Zeitwerk

У меня проблемы с 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

Во всяком случае вокруг этого? Я мог бы просто жестко закодировать RETRY_COUNT на Critical::Worker класс, но я бы не хотел этого делать.

1 ответ

Основываясь на ваших обновлениях, я вполне уверен, что у вас круговая зависимость. has_manyвызовы обрабатываются во время "инициализации ApplicationRecord". Во время "инициализации AR" один из них ссылается на Critical::Worker.foo в has_many, который ссылается ::Worker (AR) для RETRY_COUNT, который еще не инициализирован.

Если вам нужно это значение для "Время инициализации 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.

Другие вопросы по тегам