Cómo hacer que el carril de carga después de un plugin * * el código de la aplicación?
-
29-09-2019 - |
Pregunta
Estoy intentando escribir un plugin que define un modelo MongoMapper. El problema es que cuando corro script/console
, me sale este error:
/home/helder/.rvm/gems/ruby-1.8.7-p249/gems/mongo_mapper-0.8.2/lib/mongo_mapper/connection.rb:29:in
`` Base de datos ': NameError: variable de clase sin inicializar @@ nombre_basedatos en MongoMapper :: Connection`
lo que me lleva a pensar que se está tratando de cargar mi modelo plug-in antes de configurar la conexión a la base de datos. ¿Cómo hago para que se cargue el plugin después el resto de mi código de la aplicación?
Solución
voy a tratar de abordar tanto el error que me encontré, así como la cuestión general como se indica en el título.
El error específico
me di cuenta de cuál era el problema. Como dije en un comentario anterior, el problema es que los carriles (2.3.8), cuando se utiliza ActiveRecord, primeros establece la conexión de base de datos, a continuación, carga gemas, luego plugins (en este orden). Así que si tiene algún complemento que necesitan acceder a la base de datos durante la inicialización (es decir, dentro de init.rb
del plugin o algún otro archivo require
d por éste), todo funciona bien.
Sin embargo, cuando se utiliza MongoMapper, rieles cargas de MongoMapper clases , junto con todas las otras gemas / plugins, pero no establecer su conexión (rieles no lo hace, y el plugin no se dispara que en sí tampoco). La forma en que actualmente se recomienda en la documentación de MongoDB es crear una inicializador de la siguiente manera:
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = "#myapp-#{Rails.env}"
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
MongoMapper.connection.connect_to_master if forked
end
end
Sin embargo, desde plugins se inicializan antes archivos en config/initializers
están a cargo, si se intenta definir un modelo MongoMapper, tan pronto como se pone a una llamada que acceden a la base de datos (como una llamada a la key
método de clase), BOOM. Se obtiene el error citado en la pregunta.
Una manera de resolver esto es no requerir en init.rb
los archivos que necesitan la base de datos, sino que sólo añaden a la vía de carga (si no están en lib/
o app/models
, que Rieles agrega automáticamente a la ruta de carga). De esta manera, los modelos sólo se require
d por el cargador de clases de auto Rails cuando se hace referencia, que normalmente será dentro de su código de aplicación. Para entonces, la conexión db ya estará configurado. Por supuesto, esto sólo funciona si efectivamente No necesidad de hacer referencia a estas clases durante la inicialización de su plugin. De lo contrario, siga leyendo.
La pregunta general
¿Cómo hacer que el carril de carga de un plugin después el código de inicialización?
En init.rb
de su plug-in, un tiro lo que las necesidades de espera dentro de este bloque:
config.after_initialize do
# require my models
# do this
# do that
end
esa variable config
es lo mismo pasa al bloque que se pasa a Rails::Initializer.run
dentro de su archivo config/environment.rb
, y se pone a disposición init.rb
de su plug-in de rieles sin costo adicional.
Todo lo que pones dentro de ese bloque se ejecutará (por Rails::Initializer#after_initialize
) después todo está terminado de cargar y conseguir inicializado, pero antes de todas las solicitudes entran en juego. Disfrutar.