How to rollback Rails database migrations

When you perform database migrations in Rails you use the following command:

rake db:migrate
If you want to roll back your change to need need to find out what version your database is currently at and then roll back to a previous version:
rake db:migrate VERSION=<version to roll back to>
I've never liked this way to roll back, seems to much like hard work to me so I found a migration rollback script on the programmingishard site and simplified so that it only rollback by one version:
namespace :db do
  namespace :migrate do
    desc "Rollback the database schema to the previous version"
    task :rollback => :environment do
      previous_version = ActiveRecord::Migrator.current_version.to_i - 1
      ActiveRecord::Migrator.migrate("db/migrate/", previous_version)
      puts "Schema rolled back to previous verison (#{previous_version})."
    end
  end
end
To use this scriptlet, copy and paste the code into a file called db_rollback.rake and place it the lib/tasks directory within your Rails application.

To use it to roll back your most recent migration simply run:
rake db:migrate:rollback
Technorati Tags: , , , , , , ,

12 comments:

Ravin Dave D said...

Behold, for I am become a cow, the mo-oer of worlds.

Anonymous said...

I tried a :
"rake db:migrate VERSION=X" to see what it did ..."

It removed all my my database tables

DON'T DO IT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1

Paul Clarke said...

Useful info. I managed to rollback using "rake db:migrate VERSION=002" where the current version was named "003_add_test_data.rb" and the previous version named "002_add_price.rb". Thanks for the help.

abeacock said...

Paul, you can also just use "2" as your version number as Rails equates "002" as "2" internally anyway.

Glad you found my post some use though! :)

Roger Pack said...

rake db:migrate:down VERSION=20090326173033
might help

Puneet said...

Thanks for this tip.
Just a minor point, you are missing an "end" towards the end of your script.

Andy B said...

Cheers Puneet, I'll update it now!

Puneet said...

Also, it should be pointed out that this only works with the sequential migration numbering which I suppose, was used in older rails versions.

If your rails version use timestamp based naming of migrations, you can add the following to your environment.rb to force usage of sequential migration numbers.


config.active_record.timestamped_migrations = false

Andy B said...

Puneet, again thanks for the info! I've not played with Rails for nearly two years now (I changed jobs) so it's good to get advice on how it's changed since I wrote these posts back in 2007.

anuaimi said...

I had problems with the code. The current_version.to_i - 1 took the current version and just did a minus one. so 20100329180520 became 20100329180519 which is not what is desired. I've made some changes to the code that use the rollback method instead.

namespace :db do
namespace :migrate do
desc "Rollback the database schema to the previous version"
task :rollback => :environment do
ActiveRecord::Migrator.rollback("db/migrate/")
previous_version= ActiveRecord::Migrator.current_version.to_i
puts "Schema rolled back to previous verison (#{previous_version})."
end
end
end

Andy B said...

Cheers for your updated code, this migration rollback code is not intended for the date-based versioning (this wasn't available at the time of the original post).

I don't work with Rails anymore so thank you for the correction! :)

Rajneesh Anthony said...

Hi Andrew,

At present am working on rails 1.2.1 version. And am trying to do rake db:migrate:down VERSION=229 for which am getting "rake aborted!
Don't know how to build task 'db:migrate:down'". Is this the issue related to rails versions or am missing something.

Any idea will be helpful.