How to squash work-in-progress migrations
13 Mar 2016
We’ve all been there. Working on a Rails application and creating a bunch of intermediary migrations because of typos or exploring schema options as we go.
It does become a problem when we want to commit and push the code, yet we don’t really want to bloat the repo with 10 unnecessary migrations that are going to make it feel cluttered.
Would it be better to have only one migration in this case, without typos and adding-removing columns in the between?
And it is possible. To achieve that, i.e. squash these migrations, you just need to:
1. Look at all of your new migrations
And in your head, compute what their net effect is—in other words, after running all of these migrations, how does the DB schema change as a result?
To illustrate it roughly, suppose we have a few migrations:
# 1_first.rb
add_column :users, :ivited_by, :int
# 2_second.rb
rename_column :users, :ivited_by, :invited_by
It can be seen then that the net effect of these is a new column on users
— invited_by
of type int
.
Note it.
The example may seem quite contrived, but the process works with more complex migrations, too.
2. Remove all of the intermediary migrations but the last one
Change that last one to make all the noted changes from the step before.
Following the previous example, squashing the two migrations into one would produce:
# 2_my_migration.rb
add_column :users, :invited_by, :int
(We don’t remove the last migration too, and then create a brand-new migration to make sure the schema version in the local development database doesn’t changes, causing Rails to create invited_by
when we already have one!)
Cool! Not as hard as you thought it’d be, is it?