rails ruby-on-rails ruby activerecord

ruby on rails - rails - Comprender cómo funciona connect_connection en ActiveRecord



rails where (3)

AR llama a establish_connection solo una vez, para ActiveRecord :: Base. Todas las subclases usan una conexión.

Puede llamar manualmente para establecer la conexión usted mismo en algunas subclases. Esto es muy conveniente para usar dos bases de datos a la vez, por ejemplo

class MyMainUser < ActiveRecord::Base; end class MyOtherDb < ActiveRecord::Base; end class MyOtherUser < MyOtherDb; end MyOtherDb.establish_connection ... MyMainUser.first # uses default db MyOtherUser.first # uses other db

Sin embargo, no puede hacer consultas que crucen bases de datos.

Este código fue tomado de la clase de gem de ActiveRecord 2.3.14 ConnectionHandler

def establish_connection(name, spec) @connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec) end

Parece que cada vez que ruby ​​llama a establish_connection en el modelo, está creando un nuevo grupo de conexión.

Mi pregunta:

Si tengo 5 modelos que usan establish_connection a la misma base de datos, ¿es Rails lo suficientemente inteligente como para elegir un grupo ya existente en lugar de crear uno nuevo con las mismas credenciales de conexión? ¿Esto también sucede si mis 5 modelos son subclases de alguna clase abstracta que usa establish_connection ? ¿Siempre @connection_pools una conexión de @connection_pools si existe?

Actualización 1

Estoy hablando de un ejemplo concreto. Tienes 5 modelos con 5 conexiones diferentes, cada vez que Rails usa un modelo que ejecuta establish_connection connection. Al observar el código en ActiveRecord, cuando ejecuta establish_connection crea un nuevo grupo con conexiones a esa conexión específica. Lo que me pregunto es si cada vez que Rails llama a establish_connection un modelo, ¿crea un grupo nuevo o toma el existente?

Ejemplo: vienes a mi sitio y ves una lista de productos. Acaba de ejecutar una acción que llama a Product.all , que ejecuta establish_connection Product.all con alguna base de datos en Amazon. Luego, llego a la lista de productos, ¿qué sucede? ¿Cojo la conexión establecida o estoy creando un nuevo grupo con esa conexión?

Actualización 2

Supongo que la primera vez que Rails carga mis modelos crea pools con diferentes conexiones. Después, cuando uso algún Model.method , simplemente toma la conexión asociada con el modelo y ejecuta el método.

No estoy seguro de qué sucede cuando 2 modelos tienen dos conexiones iguales (no en la clase abstracta sino en la propia clase). ¿Esto producirá dos grupos de conexiones iguales, o ActiveRecord es lo suficientemente inteligente como para detectar este caso?


Este comentario:

# Check-out a database connection from the pool, indicating that you want # to use it. You should call #checkin when you no longer need this. # # This is done by either returning an existing connection, or by creating # a new connection. If the maximum number of connections for this pool has # already been reached, but the pool is empty (i.e. they''re all being used), # then this method will wait until a thread has checked in a connection. # The wait time is bounded however: if no connection can be checked out # within the timeout specified for this pool, then a ConnectionTimeoutError # exception will be raised.

desde: https://github.com/rails/rails/blob/dd944cbf5879e675fff541d1be7c7eb6c3382d01/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L242-251

Debería explicar la situación


Realmente no tiene que llamar a establish_connection en cada modelo. Simplemente puede hacer lo siguiente:

ActiveRecord::Base.establish_connection( { :adapter => ''mysql2'', :database => ''some_database'', :host => ''localhost'', :username => ''root'', :password => "" } )

y tendrás acceso a la conexión. (Este fragmento de código se ha extraído del código real (excepto el nombre de la base de datos :))).
Pero de acuerdo con la API, creo que Rails no toma la conexión existente de otro modelo (corrígeme si estoy equivocado).
También aquí hay un enlace a la documentación . Puede leer más sobre la conexión allí.
Espero haberte ayudado un poco.