Предотвращение "предупреждения: константа уровня B, на которую ссылается A:: B", с классами с именами в Rails

При хранении файлов в пользовательском каталоге (например: app/presenters/), как вы обеспечиваете загрузку классов с именами?

Например, если у вас есть:

Rails не загружается MegaMenu::CatalogPresenter:

CatalogPresenter.new
=> #<CatalogPresenter:0x85bca68 @_routes=nil>

MegaMenu::CatalogPresenter.new
(irb):3: warning: toplevel constant CatalogPresenter referenced by MegaMenu::CatalogPresenter
=> #<CatalogPresenter:0x85750a0 @_routes=nil>

Я создал образец приложения Rails 3.2, который воспроизводит эту проблему.

В config/application.rb приложение настроено на загрузку файлов в app/presenters/.

Ответы

Ответ 1

Я решил эту проблему, используя инструкцию require в инициализаторе. Мне это не очень нравится, но мне нравились имя структуры и классов моего приложения, они имели смысл, поэтому инициализатор был моим лучшим решением. В инициализаторе попробуйте:

require File.join(Rails.root, "app", "presenters", "mega_menu", "catalog_presenter")
require File.join(Rails.root, "app", "presenters", "catalog_presenter")

Эта проблема возникает из-за того, что autoload полагается на вызов const_missing, который не будет выполняться в вашем случае.

Когда ruby ​​сначала встречает ссылку на MegaMenu:: CatalogPresenter, файл mega_menu/catalog_presenter.rb не был включен. Стандартное рубиновое поведение заставляет его перемещаться по дереву пространства имен (фигура речи), и вместо этого он находит ссылку на каталоги верхнего уровня CatalogPresenter, так как это было включено в этот момент.

Ответ 2

Создание новых констант уровня заполнения внутри классов вызывает эту ошибку. Вы хотите что-то подобное в каталоге_presenter.rb:

class MegaMenu
  class MegaMenu::CatalogPresenter
  end
end