How to switch database connection on the fly with ActiveRecord?

The rails application at my company connects to 3 databases: 1 primary database that can be read from and written to + 2 replica databases which are read-only. We have been using the gem octopus (https://github.com/thiagopradi/octopus) to manage multiple database connections. Its API is quite simple: user = User.using(:first_replica).where ... will connect to the first replica database and run the query, any subsequent user.related_object call would also read from the first replica.

We are looking to switch to Rails’ way of managing multiple database connections (Multiple Databases with Active Record — Ruby on Rails Guides). Is there an equivalent API to do fine-grained switch like above?

Most of the time connected_to (Multiple Databases with Active Record — Ruby on Rails Guides) does the jobs for us but since our code has gone through a lot of hands and there are a lot of places where we read from a replica and then try to do a write. We are working around this with a before_update like below:

def ensure_writable_before_update
  if self.current_shard != :primary
    self.current_shard = :primary
    self.class.connection_proxy.current_shard = :primary
  end
end

This is supported by the gem octopus. Is there an equivalent way of doing this with Rails’ way of connecting to multiple database?

The best solution imo is to go through the entire code base and just read from primary if you intend to write but that may take a while for us to do. We hope to move to Rails’ way and get rid of the gem octopus as soon as possible since it’s blocking us from upgrading our Rails version.

Thank you!

1 Like