了解establish_connection如何在ActiveRecord中工作

Fil*_*lip 33 ruby activerecord ruby-on-rails

此代码取自ActiveRecord 2.3.14的gem类 ConnectionHandler

def establish_connection(name, spec)
  @connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec)
end
Run Code Online (Sandbox Code Playgroud)

似乎每次ruby调用establish_connection模型时,它都会创建一个新的连接池.

我的问题:

如果我有5个模型用于establish_connection同一个数据库,Rails是否足够聪明,可以选择一个已经存在的池,而不是创建一个具有相同连接凭据的新池?如果我的5个模型是一些使用的抽象类的子类,是否也会发生这种情况establish_connection?是否总是从@connection_pools它存在的地方选择一个连接?

更新1

我在谈论一个具体的例子.你有5个模型有5个不同的连接,每次Rails使用它执行的模型establish_connection.查看ActiveRecord中的代码,当它执行时,establish_connection它会创建一个与该特定连接有连接的新池.我想知道的是,每次Rails调用模型时establish_connection,是创建新池还是采用现有池.

示例:您访问我的网站并查看产品列表.您刚刚点击了一个调用的动作,该动作Product.all执行establish_connection到亚马逊上的某个数据库.然后,我来到产品列表,会发生什么?我是否已获取已建立的连接,或者是否正在创建具有该连接的新池?

更新2

我的猜测是,第一次Rails加载我的模型,它创建了具有不同连接的池.之后,当我使用一些时Model.method,它只是抓取与模型相关的连接并执行该方法.

我不确定当2个模型有两个相等的连接时会发生什么(不是在抽象类中而是在自习类中).这会产生两个相同的连接池,还是ActiveRecord足够智能来捕捉这种情况?

小智 17

对于ActiveRecord :: Base,AR只调用一次Establish_connection.所有子类都使用一个连接.

您可以在某些子类上自己手动调用建立连接.这对于一次使用两个数据库非常方便,例如

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
Run Code Online (Sandbox Code Playgroud)

但是,您不能执行跨数据库的查询.


bor*_*r1s 9

你真的不需要打电话establish_connection给每个模型.你可以简单地做下一个:

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

并且您将有权访问连接.(这段代码是从实际代码中提取的(数据库名称除外:))).
但根据API,我认为Rails不会从其他模型中获取现有连接(如果我错了,请纠正我).
这里还有一个文档链接.您可以在那里阅读有关连接的更多信息.
我希望我能帮助你.