aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/core.rb
diff options
context:
space:
mode:
authorEileen Uchitelle <eileencodes@gmail.com>2018-09-28 16:52:54 -0400
committerEileen Uchitelle <eileencodes@gmail.com>2018-10-10 12:13:46 -0400
commit31021a8c85bb80300deb01db96876858ff417f4a (patch)
tree1d41985417f6c73799ff5cd6f60429e8967190a6 /activerecord/lib/active_record/core.rb
parent58999af99fa485f748ab33d4aa4254a4b4a50991 (diff)
downloadrails-31021a8c85bb80300deb01db96876858ff417f4a.tar.gz
rails-31021a8c85bb80300deb01db96876858ff417f4a.tar.bz2
rails-31021a8c85bb80300deb01db96876858ff417f4a.zip
Basic API for connection switching
This PR adds the ability to 1) connect to multiple databases in a model, and 2) switch between those connections using a block. To connect a model to a set of databases for writing and reading use the following API. This API supercedes `establish_connection`. The `writing` and `reading` keys represent handler / role names and `animals` and `animals_replica` represents the database key to look up the configuration hash from. ``` class AnimalsBase < ApplicationRecord connects_to database: { writing: :animals, reading: :animals_replica } end ``` Inside the application - outside the model declaration - we can switch connections with a block call to `connected_to`. If we want to connect to a db that isn't default (ie readonly_slow) we can connect like this: Outside the model we may want to connect to a new database (one that is not in the default writing/reading set) - for example a slow replica for making slow queries. To do this we have the `connected_to` method that takes a `database` hash that matches the signature of `connects_to`. The `connected_to` method also takes a block. ``` AcitveRecord::Base.connected_to(database: { slow_readonly: :primary_replica_slow }) do ModelInPrimary.do_something_thats_slow end ``` For models that are already loaded and connections that are already connected, `connected_to` doesn't need to pass in a `database` because you may want to run queries against multiple databases using a specific role/handler. In this case `connected_to` can take a `role` and use that to swap on the connection passed. This simplies queries - and matches how we do it in GitHub. Once you're connected to the database you don't need to re-connect, we assume the connection is in the pool and simply pass the handler we'd like to swap on. ``` ActiveRecord::Base.connected_to(role: :reading) do Dog.read_something_from_dog ModelInPrimary.do_something_from_model_in_primary end ```
Diffstat (limited to 'activerecord/lib/active_record/core.rb')
-rw-r--r--activerecord/lib/active_record/core.rb3
1 files changed, 3 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 392602bc0f..b53681ee20 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -124,6 +124,8 @@ module ActiveRecord
mattr_accessor :belongs_to_required_by_default, instance_accessor: false
+ mattr_accessor :connection_handlers, instance_accessor: false, default: {}
+
class_attribute :default_connection_handler, instance_writer: false
self.filter_attributes = []
@@ -137,6 +139,7 @@ module ActiveRecord
end
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
+ self.connection_handlers = { writing: ActiveRecord::Base.default_connection_handler }
end
module ClassMethods