# Rescuing migrations

**URL:** <https://www.ruby-forum.com/t/rescuing-migrations/122451>\
**Category:** Rails\
**Created:** [December 7, 2007, 6:27pm UTC](https://www.ruby-forum.com/t/rescuing-migrations/122451 "2007-12-07T18:27:11Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![student](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@student](https://www.ruby-forum.com/u/student)\
**Post date:** [December 7, 2007, 6:27pm UTC](https://www.ruby-forum.com/t/rescuing-migrations/122451/1 "2007-12-07T18:27:11Z")

</div>

DHH will probably hate my example, but…

AWDR talks about the difficulties and dangers of using complex  
migrations–complex being defined as “doing more than one thing”. Not  
being satisfied with the alternatives, I have come up with a system,  
which people might want to consider for best practice. Example:

class CreateUsers \< ActiveRecord::Migration  
def self.up

```
create_table :users do |t|
  t.column :username, :string, :null => false
  t.column :salt, :string
  t.column :pw, :string, :null => false
  t.column :expires, :datetime, :null => false
  t.column :perm0, :int, :default => 0, :null => false
end

begin
  add_index(:users, :username, :unique => true)
  User.send(:reset_root, 'Hownowbrowncow')
rescue Exception => e
  down rescue STDERR.puts "Nested exception executing

```

CreateUsers.down:\n#{$!}"  
raise e  
end  
end

def self.down  
drop\_table :users  
end  
end

===

What we need to do is to ensure that any schema changes which are  
completed before the migration ends are unwound if a fail occurs later  
in the migration. In this simple example, we have one independent  
schema change (create\_table) followed by a pair of actions which may  
or may not succeed. We contain these later actions in a block with a  
rescue clause which unwinds the earlier schema changes. We use a  
rescue clause on the unwinding action because it is the first error  
which must be addressed–later errors are expected to be less  
interesting.

If we had instead created two tables first, then we would nest blocks,  
and drop only the first table if an exception occurs before the second  
is created.

Comments?
