2011-03-01 11 views
7

Tal como está ahora, no puede volver a abrir las clases del motor contenidas en el directorio /app del motor simplemente agregando la misma clase en el directorio /app de la aplicación principal. Por ejemplo:Reapertura de Rails 3 clases de motor desde la aplicación principal

/my_engine/app/controllers/users_controller.rb 
/my_app/app/controllers/users_controller.rb 

El archivo de my_engine ni siquiera se carga si existe un archivo con el mismo nombre en la aplicación de los padres. Más detalles aquí:

http://www.cowboycoded.com/2011/02/28/why-you-cant-reopen-rails-3-engine-classes-from-the-parent-app/

Busco a una solución que permita que una gota del mismo nombre de archivo/clase en el mismo camino que la aplicación de los padres, y volver a abrir en lugar de sobrescribir la clase. Tal vez me estoy perdiendo algo obvio. Puedo hacer que esto funcione con un archivo separado (nombre de archivo diferente) que usa class_eval, pero no estoy muy contento con esa solución. ¿Alguna idea sobre una solución elegante para esto?

También me pregunto si hay una razón detrás de esta restricción, o es solo el resultado de cómo los rieles cargan archivos (ver el enlace incluido) y no intencional. Me parece que cambiar el comportamiento de carga de los motores para permitir la reapertura de clases de esta manera sería una buena característica en los rieles. Sé que me confundió al principio, y estoy seguro de que otros desarrolladores también tendrán problemas con este problema.

+0

yo encontramos este que tiene un parche: http://stackoverflow.com/q/5045068/378044 – johnmcaliley

Respuesta

9

En Rails 3.2.2/Ruby 1.9 encienda la recarga de complementos, luego solicite la clase en el motor utilizando require_dependency antes de volver a abrir la clase y agregar funcionalidad. Esto funciona incluso en entornos de desarrollo (es decir, recarga de clase).

# development.rb 
config.reload_plugins = true 

# app/controllers/my_engine/documents_controller.rb 
require_dependency MyEngine::Engine.root.join('app', 'controllers', 'my_engine', 'documents_controller').to_s 

module MyEngine 
    class DocumentsController 
    def show 
     render :text => 'different' 
    end 
    end 
end 
+0

No estoy seguro, pero tal vez "config.reload_plugins = true" es opcional. No lo necesita si carga el complemento desde una ruta local (en su Gemfile) –

Cuestiones relacionadas