Working across teams, we always need to keep the database in sync with code changes, with migrations across branches and more.
To sync up, or when setting up a new database, we run the following commands:
# Create Database
rails db:create
# Populate Seed Data
rails db:seed
# Sync up migrations on current branch
rails db:migrate
Rails 6 adds rake db:prepare
to take care of the above for us,
and prepare the database for use
of the required database.
Problems with just migrate
Running rails db:migrate
when the database doesnt exist,
throws ActiveRecord::NoDatabaseError
.
➜ blog git:(master) ✗ rails db:migrate
rails aborted!
ActiveRecord::NoDatabaseError: FATAL: database "blog_development" does not exist
The task db:prepare
internally catches ActiveRecord::NoDatabaseError
and then runs rails db:setup
.
In other words,
if the database is correctly configured,
db:prepare
will just run the migration,
if the database already exists.
If the database does not exist,
db:prepare
ensures that it is created,
migrated and seeded with data.
Behaviour depending on presence of database
When database is present:
➜ blog git:(master) ✗ rails db:prepare
== 20190513112934 CreateArticles: migrating ===================================
-- create_table(:articles)
-> 0.0103s
== 20190513112934 CreateArticles: migrated (0.0104s) ==========================
This executed migrations on the existing database.
When a database is not present:
➜ blog git:(master) ✗ rails db:prepare
Created database 'blog_development'
This created the database and populated seed data.
The important bit is that db:prepare
always runs in an idempotent way.
This is useful when being utilized in CI scripts, staging deployments, and more.