In Rails 6.1, the rails db:prepare command was introduced to prepare the database for use.
This command idempotently sets up a database (creating the database, loading schema, and/or migrations).
Presently, if the database exists
and has tables that are not populated,
db:prepare will run all the migrations
to bring the database up to the state.
This may not be ideal in situations
where we might have pruned old migration files,
or if the database is provisioned
by a Platform as a Service (PaaS) provider.
During initial setup, PaaS providers provision an empty database.
Running db:prepare will run all the migrations
which may not be as efficient as loading the schema.
Let’s assume in our Rails application we have two migrations,
one to create model Product
and another to create model User.
In the above example, after dropping the database,
we generated a new model User,
and ran the rails db:prepare command.
This command ran both migrations,
even though the database was empty.
However in the upcoming Rails 7.1,
if we were to run the same commands,
the rails db:prepare command will load the schema
and run the remaining migrations.
In the above example,
after dropping the database,
when rails db:prepare is run,
it only runs the migration to create the User model.
However, if we were to look at the schema,
we would see that both tables are present.
This is because the rails db:prepare command will now load the schema
and then run the remaining migrations.
If the database exists but is empty, the rails db:prepare
command will simply load the schema without running any migrations
This change is achieved by using the value of ActiveRecord::SchemaMigration.table_exists?
to determine if the database has been populated with tables.
If the value is false,
the db:prepare task will load the schema,
and then run any remaining migrations.
Else, db:prepare will continue to work as it did.