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