# Rails database replica setup

While reading the official [documentation](https://edgeguides.rubyonrails.org/active_record_multiple_databases.html), I did not understand some parts of the set up. Let's me explain here.

### My setup:

* 1 main database
    
* 1 replica
    

### What I did not understand:

* Where to put the `connects_to` setting
    
* Proper/clean configuration in `database.yml`
    

### The `database.yml`

Notes:

* All environment needs `primary` and `primary_replica` otherwise Rails will raise an exception (at boot).
    
* The `*_replica` needs `replica: true`
    
* I did not put `primary` and `primary_replica` inside `default` because any change in a sub-object will erase all properties (I think)
    
* In that example, only production has a proper replica with different settings
    

```yaml
default: &default
  adapter: trilogy
  encoding: utf8mb4
  pool: 5
  database: <%= ENV.fetch('DB_NAME') { 'db_name' } %>
  username: <%= ENV.fetch('DB_USER') { 'user' } %>
  password: <%= ENV.fetch('DB_PASS') { 'password' } %>
  host: <%= ENV.fetch('DB_HOST') { 'db.example.com' } %>
  port: <%= ENV.fetch('DB_PORT') { '3306' } %>

development:
  primary:
    <<: *default
  primary_replica:
    <<: *default
    replica: true

test:
  primary:
    <<: *default
  primary_replica:
    <<: *default
    replica: true

staging:
  primary:
    <<: *default
  primary_replica:
    <<: *default
    replica: true

production:
  primary:
    <<: *default
  primary_replica:
    <<: *default
    username: <%= ENV.fetch('DB_USER_REPLICA') { 'user_replica' } %>
    password: <%= ENV.fetch('DB_PASS_REPLICA') { 'password_replica' } %>
    host: <%= ENV.fetch('DB_HOST_REPLICA') { 'db-replica.example.com' } %>
    replica: true
```

### Model set-up: `connects_to`

I thought I could use `connects_to` directly on a model (eg: `User`) but no, it should be on `an abstract_class or ActiveRecord::Base` (what the exception says) but I didn't understand it. I thought I should put `abstract_class` on the `User` but no, it should the parent class `ApplicationRecord` or anything other parent class (eg: `AdminApplicationRecord` for admin user).

```ruby
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  connects_to database: {
    writing: :primary,
    reading: :primary_replica
  }
end
```

If it helped, please share it.

Have fun, bye.
