1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #40484 from eileencodes/add-docs-for-per-db-connection-switching

Add documentation for granular connection switching
This commit is contained in:
Eileen M. Uchitelle 2020-10-29 16:48:37 -04:00 committed by GitHub
commit a50333b51e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -113,8 +113,7 @@ class AnimalsRecord < ApplicationRecord
end
```
Then we need to
update `ApplicationRecord` to be aware of our new replica.
Then we need to update `ApplicationRecord` to be aware of our new replica.
```ruby
class ApplicationRecord < ActiveRecord::Base
@ -124,6 +123,14 @@ class ApplicationRecord < ActiveRecord::Base
end
```
Classes that connect to primary/primary_replica can inherit from `ApplicationRecord` like
standard Rails applications:
```ruby
class Person < ApplicationRecord
end
```
By default Rails expects the database roles to be `writing` and `reading` for the primary
and replica respectively. If you have a legacy system you may already have roles set up that
you don't want to change. In that case you can set a new role name in your application config.
@ -354,11 +361,11 @@ using sharding both a `role` and `shard` must be passed:
```ruby
ActiveRecord::Base.connected_to(role: :writing, shard: :default) do
@id = Record.create! # creates a record in shard one
@id = Person.create! # creates a record in shard one
end
ActiveRecord::Base.connected_to(role: :writing, shard: :shard_one) do
Record.find(@id) # can't find record, doesn't exist
Person.find(@id) # can't find record, doesn't exist
end
```
@ -367,10 +374,52 @@ role and the shard with the `connected_to` API.
```ruby
ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one) do
Record.first # lookup record from read replica of shard one
Person.first # lookup record from read replica of shard one
end
```
## Granular Database Connection Switching
In Rails 6.1 it's possible to switch connections for one database instead of
all databases globally. To use this feature you must first set
`config.active_record.legacy_connection_handling` to `false` in your application
configuration. The majority of applications should not need to make any other
changes since the public APIs have the same behavior.
With `legacy_connection_handling` set to false, any abstract connection class
will be able to switch connections without affecting other connections. This
is useful for switching your `AnimalsRecord` queries to read from the replica
while ensuring your `ApplicationRecord` queries go to the primary.
```ruby
AnimalsRecord.connected_to(role: :reading) do
Dog.first # Reads from animals_replica
Person.first # Reads from primary
end
```
It's also possible to swap connections granularly for shards.
```ruby
AnimalsRecord.connected_to(role: :reading, shard: :shard_one) do
Dog.first # Will read from shard_one_replica. If no connection exists for
shard_one_replica, a ConnectionNotEstablished error will be raised
Person.first # Will read from primary writer
end
```
To switch only the primary database cluster use `ApplicationRecord`:
```ruby
ApplicationRecord.connected_to(role: :reading, shard: :shard_one) do
Person.first # Reads from primary_shard_one_replica
Dog.first # Reads from animals_primary
end
```
`ActiveRecord::Base.connected_to` maintains the ability to switch
connections globally.
## Caveats
### Automatic swapping for horizontal sharding