Posts Tagged ‘migrations’

Migrations much improved in Rails 2

Friday, December 14th, 2007

I hadn’t been using migrations much in Rails 1.x. I just didn’t like the workflow – it was too clumsy, and I got annoyed at writing out the files. The workflow in 1.x was as such:

1.

script/generate migration MigrationName [--svn]

2. go and manually edit 00x_MigrationName.yml in /db/migrations to reflect your desired database changes, both up and down:

class AddCreatedAtToStaff < ActiveRecord::Migration
  def self.up
    add_column :staff, :created_at, :datetime
  end
 
  def self.down
    remove_column :staff, :created_at
  end
end

3. rake db:migrate to apply the changes to the local database.
4. svn commit and cap deploy:migrations to apply the changes to the remote database

Too long – especially step 2. I knew I should do it in principle, but CocoaMySQL is right there – especially if you make several changes in the space of a few hours. In theory it’s best practise – but in actual practise someone as lazy (and impatient) as me tends to just do it directly in the DB, then eternally put off that day where they’ll finally “move to migrations”.

It’s not even the laziness – it’s the “flow”. I’m doing other things, I’ve realised I need this field. I don’t want to stop what I’m doing and write out a damn YAML file! I want the field there, right now. Too demanding? Maybe, but like I said, the DB is right there, and the difference between a 5 second edit and 2 minutes writing the file is a lot of lost concentration.

And various other solutions, such as auto_migrations, seemed good but in practise are too flaky and a dangerous, unsupported road to take.

Enter Rails 2.0, and migrations are far, far better. The core Rails principle of “convention over configuration” is in full effect here, with excellent results.

Now the process of adding a migration is as such:

1.

script/generate migration add_created_at_to_staff created_at:datetime [--svn]

Note the convention at work here. You’re implicitly telling Rails the table to use, in this case “staff”, and the field you’re adding – in this case one of Rail’s magic “created_at” fields. You then explicitly write the fields out, which you’d have to do anyway in CocoaMySQL or similar, or manually at the mysql command line.

2. rake db:migrate to apply the changes to the local database.
3. svn commit and cap deploy:migrations to apply the changes to the remote database

That’s only one step less, but it was the biggest and most annoying one. The actual creation of the migration file and addition to svn is now a single brief, easy-to-remember line. This is now terse enough and convenient enough to enter my personal development workflow, a very welcome improvement to the framework, and an excellent demonstration of Rails’ core principles in action.