如何为所有读取查询连接到第二个DB?

时间:2016-07-17 21:19:53

标签: ruby-on-rails database

我必须编写一个应用程序,其中所有读取查询都应该发送到特定的数据库,并且所有写入查询都应该发送到不同的数据库。这两个数据库都是Postgres。

我找到Secondbase,看起来很有希望,但它没有定义一种特定的方式来完成我所追求的目标。

我认为最直接的方法是使用secondbase,然后在所有活动记录函数之前挂钩,根据需要切换连接。这看起来像是一个黑客,所以我不确定。

另一种方法是将我的所有模型子类化为我认为的read_write_版本,因为您可以在类级别定义secondbase数据库连接。这种方法似乎过于复杂。

其中一个比另一个好吗?你是否以另一种方式完成了这种行为?

1 个答案:

答案 0 :(得分:0)

我通过以下方式完成了这项工作:

为每个Rails.env创建#{Rails.env}_read#{Rails.env}_write database.yml。将写入数据库配置为#{Rails.env},以便可以运行迁移。

在每个指向适当连接的控制器函数上添加一个前挂钩:

def connect_to_read_db
  DatabaseConnector.connect_to_db('read')
end

def connect_to_write_db
  DatabaseConnector.connect_to_db('write')
end

创建一个负责交换的类和方法。

class DatabaseConnector

    class << self
        def connect_to_db(function)
            if !(Rails.env.development? || Rails.env.test?)
            if ActiveRecord::Base.connection_config[:function] != function
                Rails.logger.debug "Gathering DB details"
                seed_file = Rails.root.join('config', 'database.yml')
                loaded_yml_file = YAML::load_file(seed_file)
                connection_name = "#{Rails.env}_#{function}"
                Rails.logger.debug "attempting connection to: #{connection_name}" 
                db_details = loaded_yml_file[connection_name]
                Rails.logger.debug "database details:" 
                db_details.each do |d|
                    Rails.logger.debug(d)
                end
                ActiveRecord::Base.establish_connection(
                  adapter: db_details['adapter'],
                  port: db_details['port'],
                  pool: db_details['pool'],
                  timeout: db_details['timeout'],
                  encoding: db_details['encoding'],
                  host: db_details['host'],
                  database: db_details['database'],
                  username: db_details['username'],
                  password: db_details['password']
                )
            end
            end
        end
    end
end