John Doe
John Doe

Reputation: 59

Rails. ActiveRecord::Migration. Reversible

I read RoR guide and I don't understand the next line:

If you wish for a migration to do something that Active Record doesn't know how to reverse, you can use reversible

What does it mean "doesn't know how to reverse"? How to distinguish what Active Record can reverse and what cannot?

Upvotes: 1

Views: 338

Answers (1)

Jan Strnádek
Jan Strnádek

Reputation: 808

It's simply, there are two kinds of operations in AR migrations:

1) Rails automatically knows how to rollback (revert) those operations in migrations, for example:

def change
   add_column :users, :age, :integer
end

migration means add column age, rollback means remove column age. Or create_table, reverse operation is drop_table. This operations you can put into change method in migration and rails knows what to do when rollback / reverse those migrations.

2) Rails needs to help how to process migration and rollback process, usually it is operations which somehow modifies data.

def self.up
   add_column :users, :name, :string
   add_column :users, :surname, :string
   say_with_time 'Split username into name and surname' do
       Users.select(:username).all.each do |user|
          user.name = user.username.split(/ /)[0]
          user.surname = user.username.split(/ /)[1]
          user.save!
       end
   end
   remove_column :users, :username
end

As you can see, this operation is quite complicated. Rails does not know how to reverse this operation, so you have to write reverse operation code in self.down:

def self.down
   add_column :users, :username, :string
   say_with_time 'Join name and surname into username' do 
       User.all.each do |user|
         user.update_attributes(username: "#{user.name} #{user.surname}")
       end
   end

   remove_column :users, :name
   remove_column :users, :surname
end

and thats all...

Upvotes: 2

Related Questions