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