Proper way to back out a bad migration?

I’m curious on the best practice to remedy this situation…

I created a habtm migration but forgot the :id => false

I ran the migration (rake db:migrate)

I tried to run my tests and then go the error that made me realize I forgot the :id => false.

The question is how do I back out my changes?

Typically I do rake db:migrate VERSION=0
But that also gave me the same error about “Primary key is not allowed in a has_and_belongs_to_many join table”

So I then fired up dbconsole and manually dropped the table.

But now I even if I run rake db:migrate the join table isn’t created - probably because it ‘think’ it had run it previously.

I also can’t run db:migrate VERSION=0, since it tries to call the drop table on the table that I manually dropped.

I managed to get things working by commented out my drop_table command in my migration and then running db:migrate VERSION=0, then doing rake db:migrate
and now I’m ok, but I’d think there would have been easier approach to fix things?

Rick R wrote in post #966751:

I'm curious on the best practice to remedy this situation...

I created a habtm migration but forgot the :id => false

I ran the migration (rake db:migrate)

I tried to run my tests and then go the error that made me realize I
forgot
the :id => false.

The question is how do I back out my changes?

rake db:rollback (assuming you wrote your down method correctly in the
migration!).

Best,

Typically I do rake db:migrate VERSION=0
But that also gave me the same error about "Primary key is not allowed in a
has_and_belongs_to_many join table"

So I then fired up dbconsole and manually dropped the table.

But now I even if I run rake db:migrate the join table isn't created -
probably because it 'think' it had run it previously.

I believe the problem you've been running into is that your schema
migrations table still has the number of the migration(s) you removed
manually. When the rake task runs it sees the numbers there and says
"OK, that one is done" so it skips the migration. I think the best
thing to do in that case is to manually delete the record(s) in the
schema migrations table in order to be able to rerun them.

Well, there are at least two ways:

  1. Create a table with the same name so that the down migration will be able to DROP it and then recreate it.

    rake db:migrate:redo

might work for this (since you didn’t specify your rails version)

  1. Make db:migrate think that you’re at the right version

    2a) for older ActiveRecord, set the version in the schema_info table from the database console

     update schema_info set version = ###;
    

    2b) for newer ActiveRecord, remove the migration from the schema_migrations table

     delete from schema_migrations where version = "201012ddhhmmss";
    

Then you can run your db:migrate (which you’ve already fixed).

-Rob

Rob Biedenharn

Rob@AgileConsultingLLC.com http://AgileConsultingLLC.com/

rab@GaslightSoftware.com http://GaslightSoftware.com/