我有一个带有两个数据库后端的Ruby on Rails应用程序 - PostgreSQL和MemSQL(一个与MySQL兼容的分析数据库)。
如何设置Model
以便它同时保存到两个数据库 ,以便在两者上执行CREATE,UPDATE和DELETE语句,并且仅执行SELECT查询在PostgreSQL上?
换句话说 - 如何使用相同的ActiveRecord模型维护两个数据库后端始终相同?
答案 0 :(得分:1)
你可以通过拥有两个模型类来实现这一点。但是在构图和复杂性方面,缺点很多。 ActiveRecord通过将连接保存在基类中来共享连接:
class MemSQLBase < ActiveRecord::Base
establish_connection configurations['memsql'][Rails.env]
self.abstract_class = true
end
class Post < ApplicationRecord
after_save :push_to_memsql!
def push_to_memsql!
MemSQLPost.save_or_update!(self.attributes)
end
end
class MemSQLPost < MemSQLBase
self.table_name = :posts
def self.model_name
ActiveModel::Name.new("Post")
end
end
尴尬的部分是在Post和MemSQLPost之间共享代码,你必须使用模块,因为它们不共享基类。
可以通过monkeypatching类连接方法来避免这种情况:
# this class does nothing except holding the connection pool
class MemSQLBase < ActiveRecord::Base
establish_connection configurations['memsql'][Rails.env]
self.abstract_class = true
end
module MemSQLMonkeyPatch
extend ActiveSupport::Concern
class_methods do
def connection_pool
MemSQLBase.connection_pool
end
def retrieve_connection
MemSQLBase.retrieve_connection
end
def connected?
MemSQLBase.connected?
end
def remove_connection(klass = self)
MemSQLBase.remove_connection
end
end
end
class Post < ApplicationRecord
after_save :push_to_memsql!
def push_to_memsql!
MemSQLPost.save_or_update!(self.attributes)
end
end
class Post < MemSQLBase
include MemSQLMonkeyPatch
self.table_name = :posts
end
我没有测试过这个,所以你是独自一人。