# Terminal
bin/rails db:system:change --to=postgresql
docker compose up
bin/rails g model user name email
bin/rails g model car manufacture car_model --database cars
bin/rails g active_record:multi_db
# docker-compose.yml
version: '2'
services:
postgresql-primary:
image: docker.io/bitnami/postgresql:14
ports:
- '5432:5432'
volumes:
- 'postgresql_primary_data:/bitnami/postgresql'
environment:
- POSTGRESQL_REPLICATION_MODE=master
- POSTGRESQL_REPLICATION_USER=repl_user
- POSTGRESQL_REPLICATION_PASSWORD=repl_password
- POSTGRESQL_USERNAME=postgres
- POSTGRESQL_PASSWORD=postgres
- ALLOW_EMPTY_PASSWORD=yes
postgresql-replica:
image: docker.io/bitnami/postgresql:14
ports:
- '5433:5432'
depends_on:
- postgresql-primary
volumes:
- 'postgresql_replica_data:/bitnami/postgresql'
environment:
- POSTGRESQL_REPLICATION_MODE=slave
- POSTGRESQL_REPLICATION_USER=repl_user
- POSTGRESQL_REPLICATION_PASSWORD=repl_password
- POSTGRESQL_MASTER_HOST=postgresql-primary
- POSTGRESQL_USERNAME=postgres
- POSTGRESQL_PASSWORD=postgres
- POSTGRESQL_MASTER_PORT_NUMBER=5432
- ALLOW_EMPTY_PASSWORD=yes
volumes:
postgresql_primary_data:
driver: local
postgresql_replica_data:
driver: local
# config/database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
primary:
<<: *default
database: template_development
username: postgres
password: postgres
host: localhost
port: 5432
primary_replica:
<<: *default
database: template_development
username: postgres
password: postgres
host: localhost
port: 5433
replica: true
cars:
<<: *default
database: car_development
username: postgres
password: postgres
host: localhost
port: 5432
migrations_paths: db/cars_migrate
cars_replica:
<<: *default
database: car_development
username: postgres
password: postgres
host: localhost
port: 5433
replica: true
test:
<<: *default
database: template_test
production:
<<: *default
database: template_production
username: template
password: <%= ENV["TEMPLATE_DATABASE_PASSWORD"] %>
# models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
connects_to database: { writing: :primary, reading: :primary_replica }
end
# config/initializers/multi_db.rb
Rails.application.configure do
config.active_record.database_selector = { delay: 2.seconds }
config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end
# models/cars_record.rb
class CarsRecord < ApplicationRecord
self.abstract_class = true
connects_to database: { writing: :cars, reading: :cars_replica }
end
# models/car.rb
class Car < CarsRecord
end
# bin/rails -T | grep db
rails db:create # Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to creating the development and test databases, except when DATABASE_URL is present
rails db:create:cars # Create cars database for current environment
rails db:create:primary # Create primary database for current environment
rails db:drop # Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to dropping the development and test databases, except when DATABASE_URL is present
rails db:drop:cars # Drop cars database for current environment
rails db:drop:primary # Drop primary database for current environment
rails db:encryption:init # Generate a set of keys for configuring Active Record encryption in a given environment
rails db:environment:set # Set the environment value for the database
rails db:fixtures:load # Loads fixtures into the current environment's database
rails db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)
rails db:migrate:cars # Migrate cars database for current environment
rails db:migrate:down # Runs the "down" for a given migration VERSION
rails db:migrate:primary # Migrate primary database for current environment
rails db:migrate:redo # Rolls back the database one migration and re-migrates up (options: STEP=x, VERSION=x)
rails db:migrate:redo:cars # Rolls back cars database one migration and re-migrates up (options: STEP=x, VERSION=x)
rails db:migrate:redo:primary # Rolls back primary database one migration and re-migrates up (options: STEP=x, VERSION=x)
rails db:migrate:status # Display status of migrations
rails db:migrate:status:cars # Display status of migrations for cars database
rails db:migrate:status:primary # Display status of migrations for primary database
rails db:migrate:up # Runs the "up" for a given migration VERSION
rails db:prepare # Runs setup if database does not exist, or runs migrations if it does
rails db:reset # Drops and recreates all databases from their schema for the current environment and loads the seeds
rails db:reset:cars # Drops and recreates the cars database from its schema for the current environment and loads the seeds
rails db:reset:primary # Drops and recreates the primary database from its schema for the current environment and loads the seeds
rails db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n)
rails db:rollback:cars # Rollback cars database for current environment (specify steps w/ STEP=n)
rails db:rollback:primary # Rollback primary database for current environment (specify steps w/ STEP=n)
rails db:schema:cache:clear # Clears a db/schema_cache.yml file
rails db:schema:cache:dump # Creates a db/schema_cache.yml file
rails db:schema:dump # Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)
rails db:schema:dump:cars # Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) for cars database
rails db:schema:dump:primary # Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) for primary database
rails db:schema:load # Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the database
rails db:schema:load:cars # Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the cars database
rails db:schema:load:primary # Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the primary database
rails db:seed # Loads the seed data from db/seeds.rb
rails db:seed:replant # Truncates tables of each database for current environment and loads the seeds
rails db:setup # Creates all databases, loads all schemas, and initializes with the seed data (use db:reset to also drop all databases first)
rails db:setup:cars # Creates the cars database, loads the schema, and initializes with the seed data (use db:reset:cars to also drop the database first)
rails db:setup:primary # Creates the primary database, loads the schema, and initializes with the seed data (use db:reset:primary to also drop the database first)
rails db:version # Retrieves the current schema version number
rails test:db # Run tests quickly, but also reset db