无法在Rails 3.2中连接到两个PostgreSQL数据库。

3
我尝试了一些在Stack Overflow上找到的连接两个数据库的Rails方法,但是它们都没有起作用。目前我所拥有的如下:
在database.yml文件中有两个连接设置:
development:
  adapter: postgresql
  host: localhost
  database: blerg
  username: postgres
  encoding: utf8

production:
  blah...

test: &test
  blah...

cucumber:
  <<: *test

static_api_development:
  adapter: postgresql
  host: localhost
  database: blerg-static-api
  username: postgres
  encoding: utf8

static_api_production:
  blah...

static_api_test:
  blah...

然后我在Rails应用程序中有很多常规模型,但也有一些需要连接到其他数据库的特殊模型,以下是我的设置方法...
在models文件夹中有一个名为static_table.rb的模块,其中包含以下内容:
class StaticTable < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "static_api_#{Rails.env}"
end

那么需要其他表的特殊模型有以下内容:
class ContentItem < StaticTable
  self.table_name = 'content_items'
end

然而,如果您在控制器中调用ContentItem.all,则会显示“content_items”表不存在,并且数据库连接显示为“blerg”,而不是应该是“blerg-static-api”。
非常感谢您的帮助。

WAGs:缓存的连接细节?也许数据库名称应该用双引号括起来? - bma
2个回答

1
尝试在`ContentItem`中也使用`establish_connection`。

这个答案虽然很短,但实际上是有效的。非常感谢! - CafeHey
@rmagnum2002 嗯,这是正确的答案,我尝试了其他更长的答案,但它们略有不同并且没有起作用。这个一行的答案非常准确。我想可能会少一些积分,也许一半吧,但我可以看到在它过期后给他完整的赏金的方法,如果可以的话,我会这样做的。 :( - CafeHey

0

问题在于继承不是那样工作的。

考虑一下#establish_connection的来源:

def establish_connection(owner, spec)
  @class_to_pool.clear
  raise RuntimeError, "Anonymous class is not allowed." unless owner.name
  owner_to_pool[owner.name] = ConnectionAdapters::ConnectionPool.new(spec)
end

假设为简便起见,owner_to_pool 实际上是 @owner_to_pool

在 StaticTable 类内部,你在类的上下文中调用了 establish_connection。这会更新 StaticTable 的实例变量 @class_to_pool@owner_to_pool(有些人称其为类实例变量)。this question 中的回答对此进行了详细说明。

主要问题是,即使 ContentItem 扩展了 StaticTable,它也没有继承 @class_to_pool@owner_to_pool,因此不知道它应该建立到 static_api_* 的连接。

有两种方法可以解决这个问题。首先,您可以在每个应该使用static_api_*连接的模型中使用establish_connection。这很简单,但不够DRY。更好的方法是创建一个Rails concern并将其包含在必要的模型中。

module StaticConnectionConcern
  extend ActiveSupport::Concern
  included do
    establish_connection "static_api_#{Rails.env}"
  end
end

然后在你的模型中,

class ContentItem < ActiveRecord::Base
  include StaticConnectionConcern
end

使用Rails concerns时,当StaticConnectionConcern被包含在ContentItem中时,无论included块中包含什么内容,都会在ContentItem的类上下文中调用。您可以创建一个app/concerns目录来存放concerns,然后通过编辑config/application.rb告诉Rails自动加载它们:
config.autoload_paths += %W(#{Rails.root}/app/concerns)

我强烈推荐第二种方式。随着您的应用程序变得越来越复杂,StaticConnectionConcern 可能会增加其他方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接