I’m usually really careful with Rails migrations. At a previous job I implemented a home-spun build system which included a migration-like feature. That experience gave me a lot of insight into how fragile migrations can be.
Well, today I ran into my first migration problem in some time. On Friday, I started implementing a major new feature of the project I’m working on. Like a good little programmer, I created a branch in my versioning tool of choice (git).
Today, I came back from a long weekend and hadn’t finished that feature. I needed to wait to talk to Adrian a bit before going ahead, so I decided to work on a couple of small problems instead. I switched back to my main branch, implemented the small stuff, and pushed it live (we’re still in alpha here, so I push pretty often).
A couple of hours ago I finally got that conversation with Adrian in, finished off Friday’s feature, and merged it back into the main branch. I thought the merge would be smooth but I got a conflict. No big deal, I thought, until I saw where the conflict was: in schema.rb. The conflicting line was the schema version.
Oh, no big deal (I thought again) it’s just because I haven’t migrated up my main branch. So I fixed the conflict, ran my migrations, and (like a good little programmer) kicked off my unit tests.
FAIL
Uh-oh. WTF!? Confusion and frustration, all at the same time. It appeared one of my tables from Friday’s big-feature-branch didn’t exist in my database. Then it dawned on me. I had inadvertently applied migrations out of order. You see, my minor changes this morning had minor migrations associated with them. So that table I added on Friday got lost. And I didn’t even notice, because I was working in isolated branches!
There are a few ways you can fix something like this - I opted for using rake to roll the database schema back to the last known good version, then migrate up from there. This worked on development and in production, because (as I said) we are in alpha mode here, so a little downtime is OK (it took literally 30 seconds). But if we were in beta or production mode, I would have been in trouble.
Moral is, watch out for those migrations - especially when branches are involved! They are pretty easy to screw up.