【问题标题】:Cannot connect to two postgres databases in rails 3.2.无法连接到 rails 3.2 中的两个 postgres 数据库。
【发布时间】:2013-07-16 14:39:45
【问题描述】:

我已经尝试了一些在堆栈溢出中发现的方法来连接到 rails 2 中的两个数据库,但是它们都没有工作。这是我目前得到的:

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:缓存的连接详细信息?也许数据库名称应该用双引号括起来?

标签: ruby-on-rails-3 postgresql database-connection multiple-databases


【解决方案1】:

也尝试在ContentItem 中使用establish_connection

【讨论】:

  • 这个确实有效,尽管它是最短的答案哈哈。非常感谢!
  • @rmagnum2002 这是正确的答案,我尝试了其他更长的答案,但它们略有不同并且不起作用。这一行答案是正确的。我认为有些积分会消失,也许是一半,我可以找到一种方法在到期后给他全部赏金,或者我会。 :(
【解决方案2】:

问题是继承不能那样工作。

考虑#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。这将更新@class_to_pool@owner_to_pool,它们是StaticTable 的实例变量。 (有些人将这些称为类实例变量。)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 关注点,当 StaticConnectionConcern 包含在 ContentItem 中时,included 块内的任何内容都会在 ContentItem 的类上下文中调用。您可以为关注点创建一个app/concerns 目录,然后通过编辑config/application.rb 告诉Rails 自动加载它们:

config.autoload_paths += %W(#{Rails.root}/app/concerns)

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

【讨论】:

    猜你喜欢
    • 2017-11-12
    • 1970-01-01
    • 2016-07-31
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    相关资源
    最近更新 更多