2010-12-16 10 views
14

estoy mono-remendar un motor de rieles con algo como:¿Cómo código de parche mono que se carga automáticamente en Rails?

SomeClass.class_eval do 
    # ... 
end 

La primera vez que llegué a la página web, en el modo de desarrollo, al menos, funciona, pero la segunda vez es como si mi parche nunca existió . Supongo que es Rails que vuelve a cargar automáticamente el motor (que está instalado en el proveedor /) y no vuelve a cargar mi código. Esto es Rails 2.3.

¿Alguna idea de cómo hacerlo para que mi código también se vuelva a cargar?

+0

Una vez me tocó un problema similar y la única forma de solucionarlo fue mediante la ejecución de raíles en modo de producción en mi máquina de desarrollo :(. También estoy interesado en esto. – kikito

+0

@egarcia: ay, espero que podamos encontrar una mejor solución esta vez. – Pablo

+0

¿cómo se ejecuta el código, es webbrick, mongrel o pasajero? por favor, publica los rieles y las versiones de servidor. – mpapis

Respuesta

0

Desafortunadamente, no hay forma de conectar el mecanismo de recarga de Rails 2.x. Lo que podría hacer es colocar su parche en algún lugar del directorio de la aplicación o lib. (lib/core_ext es probablemente la ubicación preferida). A continuación, agregue el directorio a autoload_paths en su configuración.

Es posible que también necesite abrir la clase, en lugar de usar class_eval.

+0

El parche mono ya está en lib/que ya está en los carriles_autoload en Rails 2. No estoy seguro por qué, pero abrir la clase con la palabra clave class en lugar de class_eval da como resultado un error, una excepción lanzada más tarde. – Pablo

4

Si coloca el parche en cualquier archivo .rb dentro/config/initializers, debería funcionar.

+0

¿cuál es la diferencia con el uso de class_eval y to_prepare? – montrealmike

0

Es feo, pero encontré que si pongo este tipo de código en la parte inferior de environments.rb, siempre se garantiza el orden de carga correcto al inicio.

18

EDITAR: Esta solución solo funciona con Rails 3 ya que depende de cierta funcionalidad en Rails :: Railtie. Pon este código en un inicializador.

Esta pregunta es bastante antiguo, pero aquí es una solución que encontré:

Rails.configuration.to_prepare do 
    SomeClass.class_eval do 
    # ... 
    end 
end 

Esto obliga rieles para recargar la clase en cada petición en el modo de desarrollo, pero sólo una vez en la producción.

+0

Esto funcionó perfectamente para mí en Rails 3. Gracias. –

+0

Esto también funcionó para mí en Rails 4 – ABMagil

+1

Trabajando para mí en Rails 5 también. – ttotherat

5

Acabo de escribir mi primer parche de mono, y por lo tanto necesitaba crear un conjunto de convenciones a su alrededor. Esto es lo que ocurrió:

  1. Coloque sus extensiones bajo lib/ext/. (. Sugerido por workmad3 veterano en #rubyonrails sala de IRC) En mi caso, estoy añadiendo un método a la clase Mail::Message (del mail gema, utilizado por ActionMailer), por lo que creó:

    /lib/ext/mail/message.rb

  2. Abrir la clase o módulo y añadir su código:

    module Mail class Message def to_is_phone? !!(self.to.first =~ /^\+1\d{10}$/) end end end

  3. Crear initalizer a cargar todos los mono-patches. Rails carga automáticamente un archivo cuando se hace referencia a una constante, pero como está agregando métodos a clases/módulos existentes en lugar de definir nuevos, eso no funcionará, por lo que debe solicitar manualmente todos sus parches de mono.Así que creé:

    /config/initializers/monkey_patches.rb

    que contiene:

    require 'ext/mail/message'

+0

Tenga en cuenta que actualmente estoy utilizando Rails 4.1, pero creo que esto debería funcionar en versiones anteriores también. – odigity

+3

'monkey_patches.rb'can ser en cambio' Dir [Rails.root.join ('lib/ext/*. Rb')]. Cada {| archivo | require file} 'y todos los parches de mono serán recogidos. – dankohn

Cuestiones relacionadas