Migration up and down

Hi --

In a migration there's an up and down method. But how does it work, really?

This was found at http://www.rabbitcreative.com/articles/2006/03/29/ruby-on-rails-super-easy-migrations-tutorial

"class CreatePeople < ActiveRecord::Migration def self.up    create_table :people do |t|      # t.column :name, :string    end end

def self.down    drop_table :people end end"

Or this from Agile Web Development with Rails.

"The up( ) method is responsible for applying the schema changes for this migration while the down( ) method undoes those changes. Let’s make this more concrete. Here’s a migration that adds an e_mail column to the orders table. class AddEmailColumnToOrders < ActiveRecord::Migration def self.up add_column :orders, :e_mail, :string end def self.down remove_column :orders, :e_mail end See how the down( ) method undoes the effect of the up( ) method."

Yes, I see !?? But...hmm...no.

For a newbie like me the above will first create the table/column and then drop/remove it. But it doesn't. Why? How do you deal with up and down and rake commands? Should I have a new migrate file if I want to add a column or do I use the same? I don't get it.

The up and down methods only have an effect when they're actually executed :slight_smile: When you do this:

   rake migrate

all new migrations have their up methods executed. "New" means: filename indicates a level higher than the index number stored in the database (in the special table schema_info). So if schema_info is "3", and you have:

   001_create_somethings.rb    002_do_something_else.rb    003_create_others.rb    004_correct_some_mistake.rb    005_yet_another_migration.rb

the up methods in 004... and 005... will be run.

At that point, if you do this:

   rake migrate VERSION=2 # migrate backwards to version 2

the down methods in 005, 004, and 003 will be run (in that order), and the number "2" will be inserted into schema_info. You can, if you wish, then delete, rewrite, or correct 003, 004, and 005. When you migrate back up, it's as if they're being seen for the first time (assuming the down methods completely reversed them).

As for writing a new migration or fixing an old one, here are the main considerations:

1. Is anyone else sharing the migrations directory? If so, you should generally migrate forward and not edit old migrations. (And you have to synchronize migration numbers, but that's another story....)

2. Do you have data you care about in the database? Backing out of migrations, at least those with drop_table commands in their down methods, will remove data from the database.

3. Are the migrations truly reversable? If not -- if the down methods are not really able to reverse everything -- then it's best to keep migrating forward.

4. Is the thing you're fixing due to a mistake, or is it just a design change? If it's a mistake (like a typo in a table name), that's a stronger argument for migrating backwards, fixing the typo, and migrating forward. If it's a design change, just migrate forward (a new migration), since that way you preserve a record of the whole design process.

David