Предотвращение "предупреждения: константа уровня 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