我正在运行Rails5,我有一个应用程序,我想根据子域更改数据库...使用过去的question/answer(基于Rails 3)我能够构建一些东西有点作品。我修改了我的基本模型以使用自定义连接处理程序,但它只在服务器启动时运行,而不是在每个请求上运行。
这是我的基础型号&自定义连接处理程序:
class CustomConnectionHandler < ActiveRecord::ConnectionAdapters::ConnectionHandler
def initialize
super
@pools_by_subdomain = {}
end
# Override the behaviour of ActiveRecord's ConnectionHandler to return a
# connection pool for the current domain.
def retrieve_connection_pool(krass)
# Get current subdomain somehow (Maybe store it in a class variable on
# each request or whatever)
# if (defined?(@@request)).nil?
# return
# end
#
# if @@request.host == 'localhost'
# return
# end
# if @@request.subdomain.present? #&& request.subdomain != "www"
# hard code domain for now, i have a database setup called new_site
subdomain = 'new_site'#@@request.subdomain
# end
@pools_by_subdomain[subdomain] ||= create_pool(subdomain)
end
private
def create_pool(subdomain)
conf = Rails.configuration.database_configuration[Rails.env].dup
#conf = ActiveRecord::Base.connection.instance_variable_get("@config").dup
# The name of the DB for that subdomain...
conf.update(:database => subdomain)
#resolver = ConnectionSpecification::Resolver.new(conf, nil)
# Call ConnectionHandler#establish_connection, which receives a key
# (in this case the subdomain) for the new connection pool
ApplicationRecord.establish_connection(conf)
end
end
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
self.connection_handler = CustomConnectionHandler.new
end
正如您在一些注释代码中看到的那样,我的意图是能够根据请求的子域(不同的客户端)切换池...但我的基本模型仅在第一个请求上运行永远不会再来所有其他模型都使用ApplicationRecord作为基础...所以我不知道该怎么做。任何人都可以帮助我实现目标吗?
答案 0 :(得分:0)
对于任何发现这一点的人,我都能通过Sharding实现我想做的事情。我安装了Octopus shard gem并设置了一个像文档所示的shards.yml。然后我将此代码添加到我的应用程序控制器:
around_filter :select_shard
def select_shard(&block)
# changes shard based on subdomain of host.
# if none found, it will use the default shard
shard = 'default'.to_sym
if request.subdomain.present?
shard = request.subdomain.to_sym
end
Octopus.using(shard, &block)
end
所有设置,简单且有效!