Hi, we’re building a multi-tenant app where most tenants will reside in the same database. However, we need to support the ability for some tenants to have their own private database.
I saw that rom-rb supports connecting to multiple databases during initialization, but is it possible to have a default connection and then switch the default to a different database at runtime?
The code below obviously doesn’t work but demonstrates the gist of what I’d like to achieve.
class ApplicationController < ActionController::API around_action :connect def connect custom_config = db_config_for(current_user.tenant_id) if custom_config # somehow switch the db connection to the tenant's private db ROM.env.gateways[:default].with_server(custom_config) do yield end else # if no config found, just yield and use the default connection yield end end def db_config_for(tenant_id) # lookup and return config if there is a private db for this tenant... end end
Sequel’s arbitrary servers seems to be close to what I need. Wondering if there’s possibly a way to take advantage of this?
I may have gotten this working with the following setup, still need to fully test it:
ROM::Rails::Railtie.configure do |config| config.gateways[:default] = [ :sql, **Rails.configuration.database, # use the sharded threaded connection pool pool_class: :sharded_threaded, # include arbitrary_servers and server_block extensions extensions: [:arbitrary_servers, :server_block] ] end
class ApplicationController < ActionController::API around_action :connect def connect connection = ROM.env.gateways[:default].connection # now we can switch to any database on the fly connection.with_server(host: 'localhost', database: 'testing') do connection.synchronize do yield end end end end
Anyone aware of any pitfalls to doing this with ROM?