rails application ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1 routes initializer

ruby on rails - application - ¿Inicializador de carriles que corre*después de que se carguen las rutas?



rails config (2)

Quiero establecer un atributo de clase cuando se inicie mi aplicación Rails. Requiere la inspección de algunas rutas, por lo que las rutas deben cargarse antes de que se ejecute mi código personalizado. Estoy teniendo problemas para encontrar un lugar confiable para conectar.

Esto funciona PERFECTAMENTE en el entorno de "prueba":

config.after_initialize do Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}" end

Pero no funciona en el entorno de "desarrollo" (las rutas están vacías)

Por ahora, parece que tengo cosas funcionando en modo de desarrollo ejecutando el mismo código en config.to_prepare que entiendo que sucede antes de cada solicitud. Desafortunadamente, el uso de to_prepare solo no parece funcionar en el modo de prueba, de ahí la duplicación.

Tengo curiosidad por saber por qué las rutas se cargan antes de: inicializar en modo de prueba, pero no en modo de desarrollo. Y realmente, ¿cuál es el mejor gancho para esto? ¿Hay un solo gancho que funcione para todos los entornos?

*EDITAR*

La sugerencia de mu de recargar las rutas fue genial. Me dio acceso consistente a las rutas dentro de after_initialize en todos los entornos. Sin embargo, para mi caso de uso, creo que todavía necesito ejecutar el código desde to_prepare, ya que estoy configurando un atributo de clase en un modelo y los modelos se vuelven a cargar antes de cada solicitud.

Así que esto es lo que terminé haciendo.

[:after_initialize, :to_prepare].each do |hook| config.send(hook) do User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("/n").scan(//s//(/w+)/).flatten.compact.uniq end end

Me parece un poco desordenado. Creo que preferiría hacer algo como:

config.after_initialize do User.exclude_routes_from_usernames! end config.to_prepare do User.exclude_routes_from_usernames! end

Pero no estoy seguro de si el User es el lugar correcto para examinar Rails.application.routes . Supongo que podría hacer lo mismo con el código en lib / pero tampoco estoy seguro de si eso es correcto.

Otra opción es simplemente aplicar la sugerencia de mu en to_prepare. Eso funciona, pero parece haber un retraso notable en la carga de las rutas en cada solicitud en mi entorno de desarrollo, por lo que no estoy seguro de que sea una buena opción, aunque al menos está SECA.

config.to_prepare do Rails.application.reload_routes! User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("/n").scan(//s//(/w+)/).flatten.compact.uniq end


Puede forzar la carga de las rutas antes de mirar Rails.application.routes con esto:

Rails.application.reload_routes!

Así que prueba esto en tu config/application.rb :

config.after_initialize do Rails.application.reload_routes! Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}" end

He hecho cosas similares que necesitaban para verificar las rutas (para conflictos con /:slug reload_routes! ) ¡y terminé poniendo reload_routes! y la comprobación en un config.after_initialize como lo estás haciendo.


Si está intentando ejecutar el código en un inicializador después de que se hayan cargado las rutas, puede intentar usar la opción after: :

initializer "name_of_initializer", after: :add_routing_paths do |app| # do custom logic here end

Puede encontrar los eventos de inicialización aquí: http://guides.rubyonrails.org/configuring.html#initialization-events