Ruby on rails 如何为所有读取查询连接到第二个数据库?

Ruby on rails 如何为所有读取查询连接到第二个数据库?,ruby-on-rails,database,Ruby On Rails,Database,我必须编写一个应用程序,其中所有读取查询都应该发送到特定的数据库,所有写入查询都应该发送到不同的数据库。两个数据库都是Postgres 我发现,这看起来很有希望,但它并没有定义一个具体的方式来实现我的目标 我认为最直接的方法是使用secondbase,并在所有活动记录函数上放置before钩子,以根据需要切换连接。这看起来像是一个黑客,所以我不确定 另一种方法是将我的所有模型子类化为read和write版本,因为可以在类级别定义secondbase DB连接。这种方法似乎过于复杂 其中一个比另一

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

我发现,这看起来很有希望,但它并没有定义一个具体的方式来实现我的目标

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

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


其中一个比另一个好吗?您是否以其他方式完成了此行为?

我通过以下方式完成此操作:

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

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

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
类数据库连接器

class我通过以下方式实现了这一点:

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

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

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
类数据库连接器

类指定您正在使用的数据库(例如mysql、postgres等)非常有用,因为一些数据库驱动程序库可以将读写查询路由到不同的数据库(例如,用于Java的mysql连接器可以这样做)。指定您正在使用的数据库(例如mysql、postgres等)非常有用,因为一些数据库驱动程序库可以将读写查询路由到不同的数据库(例如,MySQL connector for Java可以做到这一点)。