I have a semi-grand plan for some changes to migrations. Mostly this is motivated by the upcoming 3.0 release and wanting to get migrations in engines working.
1. Don't skip migrations with version numbers lower than "current".
I only recently tripped over this, but apparently it's been this way since 2.1 when we got timestamps masquerading as large/sparse version numbers. See ticket #4120.
rails.lighthouseapp.com/projects/8994/tickets/4120
I thought the whole point of timestamp version numbers was to be able to combine different development branches. That seems like it should run migrations older than the most recent one. I guess the alternative would be a new rake task: db:migrate:all that would run the lower-numbered versions that would otherwise be skipped.
I know there is a potential for confusion, but I don't think that confusion is any worse than now with some migrations never being run.
2. Include the contents of schema_migrations in schema.rb
The current approach for db:schema:load is to assume that all migrations in db/migrate up to the :version option have been run. This is fraught with peril. Given the issue in #1 above, it's possible to assume some skipped migrations have been run, which could really mess up your data. Since we're encouraged to rake db:schema:load to deploy, the migrations table should be populated with accurate information.
It should be pretty simple to add this info to schema.rb.
Full db dumps should probably include the full schema_migrations table contents as well.
3. Add a timestamp column to schema_migrations
I almost always want the information about when migrations were run when I'm trying to investigate an issue.
Timestamp info should not be included in a schema.rb dump, as that would both cause a lot of git thrashing and sort of be a lie when it was loaded.
4. Support for migrations in engines.
rails.lighthouseapp.com/projects/8994/tickets/2058 is pretty stale and I don't like that approach either. Since it never reached consensus I figured I'd try another approach that's worked well for Pivotal Labs' Desert system (we've been doing things that way for several years).
The basic idea is to add a method to the Migration class: migrate_engine(engine_name, target_version). You have to manually add a migration to the app's migrations, but that's nice and explicit the way we want it to be. The migration looks something like this:
class UpgradeToMarchRelease < ActiveRecord::Migration def self.up migrate_engine('users', 7) migrate_engine('blogs', 15) end
def self.down migrate_engine('users', 6) migrate_engine('blogs', 13) end end
Desert's approach of having a separate table to record plugin migrations had some problems, so I think the thing to do is add an "engine" column to schema_migrations to track them all in one place.
I've looked through the migration code and know just how to make this work - it's very straightforward. The engine support would work better if the changes 1 and 2 above were already done, but it's not dependent on them.
I'm starting to work on some patches for these changes, but I thought it might be worth throwing it out there for a reaction before getting too deeply into it.