Rails migrations: self.up and self.down versus change
Solution 1:
For many operations rails can guess what is the inverse operation (without problems). For example, in your case what is the reverse operation of add_column
to call when you rollback? Of course it's remove_column
. What is the inverse of create_table
? It's drop_table
. So in these cases rails know how to rollback and define a down
method is superfluous (you can see in the documentation the methods currently supported from the change method).
But pay attention because for some kind of operation you still need to define the down
method, for example if you change the precision of a decimal column how to guess the original precision on rollback? It's not possible, so you need to define the down
method.
As said, I suggest you to read the Rails Migrations Guide.
Solution 2:
Better to use Up, Down, Change:
On Rails 3 (Reversible): which should add new column on up and fill all records in table only on up, and only delete this column on down
def up
add_column :users, :location, :string
User.update_all(location: 'Minsk')
end
def down
remove_column :users, :location
end
But:
You had to avoid using change method which allows to save some time. For example, if you didn’t need to update column value immediately after it’s adding you would cut this code down to like this:
def change
add_column :users, :location, :string
end
On up it will add column to table and remove it on down. Much less code and it’s a profit.
On Rails 4: one more useful way to write what we need in one place:
def change
add_column :users, :location, :string
reversible do |direction|
direction.up { User.update_all(location: 'Minsk') }
end
end
Solution 3:
class AddImageToUsers < ActiveRecord::Migration
def change
add_column :users, :image_file_name, :string
add_column :users, :image_content_type, :string
add_column :users, :image_file_size, :integer
add_column :users, :image_updated_at, :datetime
end
end