Migrations are supposed to be both a way to make your database definition platform (db2, oracle, mysql, etc) agnostic, and a good way to share database changes between team members.
While it works excellently for: creating a versionable database definition, and not tying you to one database, it has several shortcomings in my eyes.
The idea is, when you make a change, it becomes a new migration. Other team members just update from source control, will now have a 024_add_something.rb, run rake migrate, and presto, they're database looks like every other developers.
The problem is, databases may change a lot. Picture a fictional accounting system with: 001_add_users.rb, 002_add_invoices.rb, 003_add_payments.rb, etc
Now, during the course of development, the users table for instance may change a lot. You may need to add new fields, maybe we changed the max length for last names, now we want to track roles/user types, someone stored home-phone as one field, but we want it broken out into area code, exchange, etc. This could be a lot of little changes. If you add a new migration for each one of these, it is MUCH harder than just looking at one create_table call in one file to see the structure.
What we end up doing is just modifying the original 001_add_users.rb. A simple rake migrate VERSON=0, followed by rake migrate brings you up to date EXCEPT that you lose all your data. Fine in development, but now you cap deploy to your test box with data that matters, and this doesn't work.
What do people think are best practices for this?
I somewhat feel that migrations, along with code in them to transform data when moving back/forward make a lot more sense once the code has reached a stable point, i.e. coinciding with actual releases.
Perhaps it would be cool if running migrate generated intermediate SQL that you could check out before creating the tables, to avoid having one table def scattered through 8 migration files.