2012-03-21 20 views
15

Al almacenar archivos en un directorio personalizado (por ejemplo: app/presenters/), ¿cómo se asegura que las clases de espacio de nombres estén cargadas?Prevención de "advertencia: constante de nivel B referenciada por A :: B" con clases de espacio de nombres en Rails

Por ejemplo, si usted tiene:

rieles no se carga 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> 

He creado un sample Rails 3.2 app that reproduces this problem.

En config/application.rb, app's configured to load files in app/presenters/.

Respuesta

17

He resuelto este problema mediante el uso de una declaración requerir en un inicializador. No me gusta mucho pero me gustaron la estructura y los nombres de clase de mi aplicación, tenían sentido, por lo que un inicializador era mi mejor solución. En el intento de inicialización:

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

Este problema se produce porque se basa en la carga automática const_missing ser llamado que no sucederá en su caso.

Cuando Ruby encuentra por primera vez una referencia a MegaMenu :: CatalogPresenter, el archivo mega_menu/catalog_presenter.rb no se ha incluido. El comportamiento estándar de ruby ​​hace que pase por el árbol del espacio de nombres (figura del discurso) y en su lugar encuentra la referencia de nivel superior CatalogPresenter, ya que esto se ha incluido en este punto.

+0

¿Esto se aplica de la misma manera al directorio de aplicaciones/modelos? Tengo una aplicación/modelos/personas/datos.rb y recibo la misma excepción porque los datos ya están definidos. – joshhepworth

+2

Esto aplicará en cualquier lugar. Es solo una cuestión de cómo se resuelven las constantes faltantes. Si se asegura de que requiere explícitamente ambos modelos, no debería encontrarse con este problema. –

0

La creación de nuevas constantes de niveles dentro de las clases plantea este error. ¿Quieres algo más como esto en catalog_presenter.rb:

class MegaMenu 
    class MegaMenu::CatalogPresenter 
    end 
end 
+0

Gracias por la sugerencia, Veraticus. Desafortunadamente, después de hacer ese cambio, el problema todavía existe. Parece que Rails no sabe que debería buscar 'app/presentadores/mega_menu/catalog_presenter.rb'. – nickh

+0

Bueno, valió la pena intentarlo. :/La única otra sugerencia que haría es agregar '' 'app/presentadores/mega_menu''' manualmente a tus rutas de autocarga y ver si eso lo corrige. – Veraticus

Cuestiones relacionadas