我正在尝试将ActiveRecord gem升级到最新的3.1.0版本并看到引发了很多异常,我认为这是由于我们如何处理多个数据库。
对于我们的每个数据库,我们指定一个单独的基类,它继承自ActiveRecord::Base
,并在那里调用establish_connection
。没有跨数据库关系。到目前为止,这对我们来说还不错。
升级到ActiveRecord 3.1.0后,我看到它在遍历关系时失败并出现ActiveRecord::ConnectionNotEstablished
异常(即它会成功从数据库中提取单个实体或一组实体,但在导航时失败到相关的课程。)
回溯的顶线是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'
,所以我稍微挖了一下。该方法定义如下:
def retrieve_connection(klass) #:nodoc:
pool = retrieve_connection_pool(klass)
(pool && pool.connection) or raise ConnectionNotEstablished
end
我的简单测试(puts Customer.first.address
)调用retrieve_connection
3次。使用Customer
作为klass
参数两次,使用ActiveRecord::Base
作为参数一次 - 这是因为establish_connection
没有为ActiveRecord::Base
调用失败。
到实际问题然后 - 是否有一种新的推荐方法来处理ActiveRecord中的多个数据库连接?如果是这样,它是什么?
如果没有,可能导致此问题的原因是什么?
答案 0 :(得分:9)
昨天我在升级到ActiveRecord 3.1.0时遇到了同样的问题。我不能说在ActiveRecord 3.1中是否有一种新的推荐方法来处理多个数据库连接,但我确实找到了解锁自己的方法。
现在必须在ActiveRecord :: Base上建立连接,以便确定适配器的表名长度/规则。除了在我的数据库初始化程序中建立的其余连接外,我现在还为我的一个数据库建立了一个ActiveRecord :: Base连接(无论哪个连接都没关系。)
我想有一个更好的解决方案可以找到,但我现在很高兴能够畅通无阻。
答案 1 :(得分:3)
我正在使用这个解决方案 - 我看到的是当在每个OtherDb类中调用establish_connection时 - 似乎有很多开销重新加载表定义,每次重新加载类def时我都会随机查看问题。
# 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