2011-09-12 14 views
8

Estoy tratando de actualizar la gema de ActiveRecord a la última versión 3.1.0 y viendo surgir muchas excepciones, creo que se debe a la forma en que manejamos varias bases de datos.bases de datos múltiples de ActiveRecord 3.1.0

Para cada una de nuestras bases de datos especificamos una clase base separada que hereda de ActiveRecord::Base, y llama al establish_connection allí. No hay relaciones entre bases de datos. Esto ha funcionado bien para nosotros hasta ahora.

Al haber actualizado a ActiveRecord 3.1.0 veo que falla con una excepción ActiveRecord::ConnectionNotEstablished, al atravesar relaciones (es decir, extraerá con éxito una sola entidad o conjunto de ellas de la base de datos, pero falla al navegar a una clase).

La línea superior del backtrace es C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:410:in 'retrieve_connection', así que profundicé un poco. El método se define como sigue:

def retrieve_connection(klass) #:nodoc: 
    pool = retrieve_connection_pool(klass) 
    (pool && pool.connection) or raise ConnectionNotEstablished 
end 

Mi prueba simple (puts Customer.first.address) llama retrieve_connection 3 veces. Dos veces con Customer como el parámetro klass, y una vez con ActiveRecord::Base como el parámetro - que es cuando falla como establish_connection no se ha llamado para ActiveRecord::Base.

A la pregunta real, entonces, ¿hay una nueva forma recomendada de manejar conexiones de bases de datos múltiples en ActiveRecord? Si es así, ¿qué es?

Si no, ¿qué podría estar causando este problema?

Respuesta

8

Me encontré con el mismo problema ayer al actualizar a ActiveRecord 3.1.0. No puedo decir si hay una nueva forma recomendada de manejar múltiples conexiones de bases de datos en ActiveRecord 3.1, pero sí encontré la manera de desbloquearme.

Parece que ahora se debe establecer una conexión en ActiveRecord :: Base para que pueda determinar las longitudes/reglas del nombre de la tabla del adaptador. Junto con el resto de mis conexiones establecidas en el inicializador de mi base de datos, ahora también tengo una conexión ActiveRecord :: Base establecida para uno de mis DB (no importa cuál).

Me gustaría pensar que hay una solución mejor para encontrar, pero estoy contento de haber sido desbloqueado por el momento.

+0

Gracias por eso, no he tenido tiempo de probarlo pero parece una buena solución. Vuelva y avísenos si encuentra una mejor manera ... –

+0

Nos hemos encontrado con el mismo problema y nos gustaría encontrar una solución mejor. Gracias por la ayuda, sin embargo. ¡Al menos ahora también estamos desbloqueados! – jasonkarns

+0

Me metí en este problema yo mismo (activerecord 3.1.3) y resolví el problema como se sugirió. Estoy de acuerdo en que una mejor solución sería más ideal. –

3

Estoy usando esta solución - Lo que estaba viendo era que cuando se llamaba connection_connection en cada una de las clases OtherDb parecía que había muchas definiciones de tablas de recarga y veía problemas al azar cada vez que se recargaba la clase. .

# The idea here is to specify that a given model should use another 
# database without having to change the entire inheritance hierarchy 

# declare model for table in primary connection 
class Bar < ActiveRecord::Base 
    # assume we have logic here that we don't want to refactor into a module 
    # but we do want to inherit in OtherDb::Bar 
end 

module Foo 

    # base model in Foo namespace - uses another db 
    class BaseConnection < ActiveRecord::Base 
    # OtherDb::Title.database contains a db config hash 
    # This would probably go in the initializers 
    establish_connection OtherDb::Title.database 
    end 

    # module used to override db connection 
    module OtherDb::Base 
    def retrieve_connection 
     # connection_handler.retrieve_connection(self) # normal behavior 
     connection_handler.retrieve_connection(Foo::BaseConnection) # use db from Foo::BaseConnection 
    end 
    end 

    # Foo::Bar is identical to ::Bar but is in another db 
    class Bar < ::Bar 
    extend OtherDb::Base 
    end 
end 
Cuestiones relacionadas