diff options
author | Eileen Uchitelle <eileencodes@gmail.com> | 2018-09-28 16:52:54 -0400 |
---|---|---|
committer | Eileen Uchitelle <eileencodes@gmail.com> | 2018-10-10 12:13:46 -0400 |
commit | 31021a8c85bb80300deb01db96876858ff417f4a (patch) | |
tree | 1d41985417f6c73799ff5cd6f60429e8967190a6 /activerecord/CHANGELOG.md | |
parent | 58999af99fa485f748ab33d4aa4254a4b4a50991 (diff) | |
download | rails-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/CHANGELOG.md')
-rw-r--r-- | activerecord/CHANGELOG.md | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 6397bc361a..00f4ee1aaa 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,39 @@ +* Add basic API for connection switching to support multiple databases. + + 1) Adds a `connects_to` method for models to connect to multiple databases. Example: + + ``` + class AnimalsModel < ApplicationRecord + self.abstract_class = true + + connects_to database: { writing: :animals_primary, reading: :animals_replica } + end + + class Dog < AnimalsModel + # connected to both the animals_primary db for writing and the animals_replica for reading + end + ``` + + 2) Adds a `connected_to` block method for switching connection roles or connecting to + a database that the model didn't connect to. Connecting to the database in this block is + useful when you have another defined connection, for example `slow_replica` that you don't + want to connect to by default but need in the console, or a specific code block. + + ``` + ActiveRecord::Base.connected_to(role: :reading) do + Dog.first # finds dog from replica connected to AnimalsBase + Book.first # doesn't have a reading connection, will raise an error + end + ``` + + ``` + ActiveRecord::Base.connected_to(database: :slow_replica) do + SlowReplicaModel.first # if the db config has a slow_replica configuration this will be used to do the lookup, otherwise this will throw an exception + end + ``` + + *Eileen M. Uchitelle* + * Enum raises on invalid definition values When defining a Hash enum it can be easy to use [] instead of {}. This |