If you are a solo developer, Rails' migrations are the neatest thing since sliced bread. If you work on a team, you know that often it can be a real pain dealing with migrations. Someone on your team checks in a new migration and you don't notice it when you svn up or git pull, and suddenly all your tests are breaking. Or even worse, someone modifies an old migration and you need to reset and migrate up from zero (we're talking development here, not production). I'm not a fan of automatically running migrations (I'll leave the reasons for you to guess), but I do like to be informed of when I'm about to run headfirst into a wall. Saves so much wear and tear on my noggin.
And so I give you the migration_concordance plugin. It's pretty darn simple. From the README:
This plugin extends Rails migrations to provide notification when you need to run migrations. It will detect both new migrations and modifications to previously run migrations. It is primarily of use for team development, but is also useful when deploying a release to a new environment to determine when migrations need to be run. This plugin does not run migrations automatically, but will notify you whenever you need to run them.
How it works
Whenever you run
rake db:migrate, the plugin takes a snapshot of the state of your migrations by generating an MD5 hash of each migration file and dumping them all in a YAML file. Put a 1-line check in your environment.rb file, and then whenever you fire up the Rails environment, a notification is printed telling you if you need to run migrations. The snapshot strategy allows it to tell when old migrations are modified, solving one of the most annoying things about using migrations on a team.
Why would anyone ever edit an old migration? Well, I think there are legitimate reasons to do so. First off, let me say you should never modify a migration that has been deployed and used in your production environment. That's just asking for trouble with a side of getting fired for incompetence. But during a development cycle, it can make sense to modify a migration. On my current project we keep a migration file for each model (or cluster of related models), and as we evolve and refactor the design of the model, we go back and modify its migration to update its schema. This makes more sense to me than having the definition of a model's schema spread out over a zillion migration files, and in practice it works really well. It's nice to only have to look in one place for a model's schema definition, and more importantly if two people modify the model's schema at the same time, it's easier to find the conflict if both changes are in the same file rather than in two different migrations. That said, there are those issues with noticing when you have to run an old migration again. Thus the plugin.
I haven't figured out exactly how to integrate this with Capistrano yet, but I think it will be handy to get a notice when migrations have to be run as part of a deployment. Stay tuned, or if you get inspired and tackle it yourself, please let me know.
How to get it
The code for migration_concordance is up on github at http://github.com/joshsusser/migration_concordance. If you're not running git (and why aren't you?), you can grab a tarball from the github page to ease your plugin installation. You can just untar into vendor/plugins - there's no install code to run. After you git clone or untar the plugin, add the following line to the end of your config/environment.rb file:
Then whenever you run script/server, script/console, or whatever, you'll get a notice of whether you need to migrate. If you want to check manually, run
rake environment to get the notice.
Lastly, make sure you add the file
db/migration_snapshot.yml to your svn:ignores property or .gitignore file. Putting the snapshot file under version control will defeat the plugin, since the snapshot will reflect the migrations that were checked in, rather than the ones that were last run on your computer.
By the way...
You've probably heard this at least twelve times in the last week, but github is totally badass. I've never had a reason to put my code up on a hosting service like that before, but now I do. github is social networking for code geeks. If you want to hack on migration_concordance yourself, get yourself a github account and fork my repo and have at it. If you do something cool, let me know so I can grab your mods. DrNic has a very useful writeup of how to manage that, if you're not already up on the planet-smashing powers of git. And Chris and Tom have said that github will be free for open source repos (of reasonable size), so there isn't even anything to pay. Sweet.