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

Document best practices with old migrations

The copy here is of course up for discussion but it feels like we need
to address the issue of old migrations in the Migration guide because
other than mentioning the canonical nature of schema.rb/structure.sql
or the actual database compared to migration files, it seems like more
guidance would help.

Here's a sample of the kinds of question people seem to often ask about
old Rails migrations:

- https://stackoverflow.com/questions/20119391/delete-old-migrations-files-in-a-rails-app
- https://www.reddit.com/r/rails/comments/4ayosd/compacting_migrations_files_or_delete_them/
- https://stackoverflow.com/questions/4248682/is-it-a-good-idea-to-purge-old-rails-migration-files
- https://stackoverflow.com/questions/707013/is-it-a-good-idea-to-collapse-old-rails-migrations
- https://stackoverflow.com/questions/1981777/rails-remove-old-models-with-migrations
- https://stackoverflow.com/questions/3343534/rebase-rails-migrations-in-a-long-running-project

The common theme seems to be: "I've got old migrations, should I keep
them around on an old project?".

My personal stance is that as long as migrations run and don't take too long do
so, you should keep them around since it allows people working on the Rails
project with you to seamlessly upgrade their local development database
without having to do a `db:drop db:schema:load` and lose all their seed data.

While writing down this suggested new section it felt like I was describing a
very cumbersome process that could be address with a rake task like:

```bash
rails db:migrate:remove VERSION=20121201123456
```

It rollback to the version just before `20121201123456`, delete the migration
file, and run `db:migrate` to get back to the latest migration.

This of course doesn't address a situation when someone would want to delete or
merge all migrations prior to a certain date, which is addressed by
[squasher](https://github.com/jalkoby/squasher).

I'm not sure this is something we want to encourage people to do. Although I
feel like with more and more production Rails apps over 5-years old, it's
definitely a concern we should address.
This commit is contained in:
Olivier Lacan 2018-07-30 16:48:42 +02:00
parent 59c3ed1b3f
commit 4a2d5efa94

View file

@ -923,9 +923,10 @@ your database schema.
It tends to be faster and less error prone to create a new instance of your
application's database by loading the schema file via `rails db:schema:load`
than it is to replay the entire migration history. Old migrations may fail to
apply correctly if those migrations use changing external dependencies or rely
on application code which evolves separately from your migrations.
than it is to replay the entire migration history.
[Old migrations](#old-migrations) may fail to apply correctly if those
migrations use changing external dependencies or rely on application code which
evolves separately from your migrations.
Schema files are also useful if you want a quick look at what attributes an
Active Record object has. This information is not in the model's code and is
@ -1042,3 +1043,21 @@ end
This is generally a much cleaner way to set up the database of a blank
application.
Old Migrations
--------------
The `schema.rb` or `structure.sql` is a snapshot of the current state of your
database and is the authoritative source for rebuilding that database. This
makes it possible to delete old migration files.
When you delete migration files in the `db/migrate/` directory, any environment
where `db:migrate` was run when those files still existed will hold a reference
to the migration timestamp specific to them inside an internal Rails database
table named `schema_migrations`. This table is used to keep track of whether
migrations have been executed in a specific environment.
If you run the `db:migrate:status` command, which displays the status
(up or down) of each migration, you should see `********** NO FILE **********`
displayed next to any deleted migration file which was once executed on a
specific environment but can no longer be found in the `db/migrate` directory.