我必须编写一个应用程序,其中所有读取查询都应该发送到特定的数据库,并且所有写入查询都应该发送到不同的数据库。这两个数据库都是Postgres。
我找到Secondbase,看起来很有希望,但它没有定义一种特定的方式来完成我所追求的目标。
我认为最直接的方法是使用secondbase,然后在所有活动记录函数之前挂钩,根据需要切换连接。这看起来像是一个黑客,所以我不确定。
另一种方法是将我的所有模型子类化为我认为的read_
和write_
版本,因为您可以在类级别定义secondbase数据库连接。这种方法似乎过于复杂。
其中一个比另一个好吗?你是否以另一种方式完成了这种行为?
答案 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