Monday, June 2, 2008

Generators and Timestamped Migrations

I've never liked the idea of timestamped migrations, still don't. So, not to my surprise, this was the first (and only) thing that bit me when testing the Lockdown generators against the latest release of Rails (2.1).

What happened? Well, the Lockdown generator generates 5 migrations, and contrary to all the speed talk surrounding Ruby, it does this in less than a second. (Yes - I know Ruby isn't super fast, but it gets the job done.)

What does this mean? Well, all migrations have the same "number" and therefore don't work. Lovely. Just lovely.

So here's what you need to add to your Rails::Generator to get around this issue:
if Rails::VERSION::MAJOR >= 2 && Rails::VERSION::MINOR >= 1
class Rails::Generator::Commands::Base
protected
def next_migration_string(padding = 3)
sleep(1)
Time.now.utc.strftime("%Y%m%d%H%M%S")
end
end
en

I'm grateful for Rails and to the Rails community. They have done a lot of really good stuff.

I only have one question, couldn't timestamped migrations have been an option? I'm not the only one who disliked the concept from the beginning.

Note: I'm not expecting anyone from the Rails team to have even heard of this blog so it's a rhetorical question.

2 comments:

Evgeny Myasishchev said...
This post has been removed by the author.
Evgeny Myasishchev said...

I got the same problem as you does. Proposed solution is nice but I have more than 10 migrations so this means 10 seconds delay...

Here what I have used to make it work:
class Rails::Generator::Commands::Base
protected
def next_migration_string(padding = 3)
next_unique_migration_num(Time.now.utc.strftime("%Y%m%d%H%M%S").to_i)
end

def next_unique_migration_num(num)
if @prev_num && @prev_num >= num
next_unique_migration_num(num += 1)
else
@prev_num = num
end
end
end