DEV Community

Cover image for Fixing a Rails Migration Snafu
Savannah Fischer
Savannah Fischer

Posted on • Updated on

Fixing a Rails Migration Snafu

I had been working on a huge new feature for a Rails app with existing customers for about two months. This new feature had about 10 new database migrations, including rolling back and editing the last migration that had been pushed to production and renaming those tables. That was a mistake. If, two months later, I had remembered to rollback the most recent migration in production before performing the new migrations, all would have been well.

Alas, I did not. Obviously, any programming change that requires you remember to do something 2 months from now is bad, especially if you have no system to remind yourself before deploying. When I did push the feature to production, my new migrations ran fine and two days laters I started getting errors about how a database table doesn't exist when my code assumes it does. It didn't take me long to realize that it was the migration about 10 migration files back that was the source of the error where I had rolled back in development and renamed the tables, but I had not rolled back in production.

Worse, I had a bunch of data live in production now, that depended on tables created in migrations after the problem migration file. I was not okay losing that data, but the only solution to my problem that I knew about required it. Basically, I was familiar with the basics of migrations through the Rails ActiveRecord migrations guide. I thought I'd have to push the old version of that migration file to production, rollback 10 migrations (losing all my new data), push the new version of the migration file and run db:migrate one more time.

Thankfully, in my desperate googling for a solution, I ran into this question and answer, which suggested a path forward. When I realized you could run a single migration up or down with the version option, it became clear. I had to push the old version of that migration to production and then run:

rails db:migrate:down VERSION=20180506181554
Enter fullscreen mode Exit fullscreen mode

Then push the new version of that migration and run:

rails db:migrate:up VERSION=20180506181554
Enter fullscreen mode Exit fullscreen mode

The version, by the way, is just the timestamp in the filename rails generates automatically if you are using rails generate migration. Knowing how to reverse and rerun a specific migration file is a huge relief. Its comforting to know getting migrations out of sync in production doesn't necessarily have to blow everything up, but has the potential to be dealt with as an isolated problem. Thanks Rails!

Top comments (4)

Collapse
 
andy profile image
Andy Zhao (he/him)

Oof yeah, migrations can be sneaky. I often run into troubles when checking out between branches. Have some tricks up my sleeve now for it, but a lot of it is getting your ducks lined up before moving on.

Collapse
 
richjdsmith profile image
Rich Smith

Would love to see a post on migrations between branches! I've struggled with that and am always keen on tips.

Collapse
 
eimihar profile image
Rahimie Ahmad

I never really liked the idea of db migration at the extent of the destructive ones such as column or table drop.. I'll always keep that one out of our options and rather figure something else for such cases..

Collapse
 
pablomarti profile image
Pablo Martí

Thank you! Actually I will try it tonight for a migration that failed and there are some other migrations after that. I do not want to do a rollback (because of this scenario).