3

我已经尝试了一些在堆栈溢出中发现的方法来连接到 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 应用程序中有很多普通模型,还有需要连接到其他数据库的奇怪的特殊模型,这就是我设置它的方式......

在模型文件夹中有一个名为 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”。

任何帮助将不胜感激谢谢。

4

2 回答 2

1

也试试establish_connectionContentItem

于 2013-07-22T22:13:44.097 回答
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在类上下文中调用。这将更新@class_to_pool@owner_to_pool,它们是StaticTable的实例变量。(有些人将这些称为类实例变量。)这个问题中接受的答案进入了详细的解释。

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

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

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目录,然后通过编辑告诉 Rails 自动加载它们config/application.rb

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

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

于 2013-07-25T15:02:29.663 回答