¿Cómo extender una clase desde un inicializador y hacer que se vuelva a cargar en el entorno de desarrollo?

Estoy extendiendo una clase (que está en un complemento) al incluir un módulo, esto se hace en un inicializador.

require 'qwerty/core/user' User.send :include, Qwerty::Core::Extensions::User 

Sin embargo, en el desarrollo antes de cada solicitud (y después de que se llama a la carga en la consola) todos los modelos se vuelven a cargar, pero como los inicializadores no se ejecutan de nuevo, el módulo no está incluido. Dejando un modelo con ‘partes faltantes’.

Debido a que el modelo está en un complemento, no parece prudente incluir código directamente en la clase, lo que sería el enfoque habitual.

Por ahora, simplemente he agregado un before_filter que incluye el módulo si está en el entorno de desarrollo. Pero he copiado / pegado y tengo un código duplicado en el controlador de inicialización y aplicación.

  # Class extensions in initalizers are over-writtern each request def development_loading if RAILS_ENV == 'development' User.send :include, Qwerty::Core::Extensions::User end end 

¿Hay alguna manera mejor?

Como nota al margen, el complemento es mío, así que podría agregarle un código, pero es posible que las extensiones que se encuentran en el módulo no siempre estén presentes …

environment.rb

 config.to_prepare do User.send :include, Qwerty::Core::Extensions::User end 

El código es el bloque que se ejecuta antes de cada solicitud en modo de desarrollo y una vez en modo de producción.

En Rails 3.x puede configurar un bloque para que se ejecute cada vez que se realicen recargas (en modo de desarrollo o cuando config.cache_classes = false ). Esto iría en un inicializador:

 ActionDispatch::Callbacks.to_prepare do # configure stuff or initialize end 

Solución ligeramente más elegante que la aceptada, ya que se puede poner en un inicializador:

 require 'dispatcher' Dispatcher.to_prepare do # stuff that needs to happen once per initialization end 

Al principio, iba a recomendar algo acerca de agregar un directorio de ‘desarrollo’ al frente de su ruta de carga en modo de desarrollo, para que sus revisiones siempre se recarguen primero … Pero luego se me ocurrió que dijo algo confuso.

El modelo que estás intentando ampliar. ¿Está en un plugin? Se supone que los complementos no deben volver a cargarse de forma predeterminada en el modo de desarrollo, a menos que la aplicación diga explícitamente que debería en su configuración al configurar Config.reload_plugins? a falso

Pero si, por alguna razón, su complemento se está cargando de todas formas y no quiere que lo haga , puede poner esto en el init.rb de su complemento para decir explícitamente que no debe recargarse:

 Dependencies.load_once_paths << lib_path 

Consulte la documentación de Rails en la clase de Configuración para obtener más detalles: http://api.rubyonrails.org/classes/Rails/Configuration.html#M002536

¿Por qué usas inicializadores para incluir funcionalidad?

Intente lo siguiente en su lugar:

 require 'qwerty/core/user' class User < ActiveRecord::Base include Qwerty::Core::Extensions::User # bla bla end