Reputation: 12422
I am having a problem to revert last migration.
Ever since I installed the 'letrate' gem for rating, any rake db:rollback
reverts precisely that letrate gem migration and NOT the last migration as expected.
I doubt this is due to the gem itself.
Any ideas how to fix this, so I can enjoy the very handy rollback?
Same identically issue with:
rake db:migrate:redo
Result:
== CreateRates: reverting ====================================================
-- drop_table(:rates)
-> 0.0224s
== CreateRates: reverted (0.0225s) ===========================================
== CreateRates: migrating ====================================================
-- create_table(:rates)
NOTICE: CREATE TABLE will create implicit sequence "rates_id_seq" for serial column "rates.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "rates_pkey" for table "rates"
-> 0.1787s
-- add_index(:rates, :rater_id)
-> 0.0032s
-- add_index(:rates, [:rateable_id, :rateable_type])
-> 0.0024s
== CreateRates: migrated (0.1850s) ===========================================
rake db:migrate:status
...
up 20121205224038 Rename user address column
up 20121206125016587 ********** NO FILE **********
up 20121206125016605 ********** NO FILE **********
up 20121210152550 Create reservations
up 20121210180233 Create transactions
up 20121210215840 ********** NO FILE **********
up 20121218144200 Create videos
up 20121218144800 Add video to videos
up 20130108225007 Devise invitable add to users
up 20130130202046 Acts as taggable on migration
up 20130205154206 Create commissions
up 20130207133520 Add user id to event transition
and the files
-rw-r--r--@ 1 joel staff 137 Dec 7 16:40 20121205224038_rename_user_address_column.rb
-rw-r--r--@ 1 joel staff 443 Dec 7 16:40 20121206125016587_create_rating_caches.rb
-rw-r--r--@ 1 joel staff 432 Dec 7 16:40 20121206125016605_create_rates.rb
-rw-r--r--@ 1 joel staff 429 Dec 10 23:30 20121210152550_create_reservations.rb
-rw-r--r--@ 1 joel staff 414 Dec 10 19:03 20121210180233_create_transactions.rb
-rw-r--r--@ 1 joel staff 237 Dec 18 15:44 20121218144200_create_videos.rb
-rw-r--r--@ 1 joel staff 172 Dec 18 16:18 20121218144800_add_video_to_videos.rb
-rw-r--r--@ 1 joel staff 758 Jan 8 23:50 20130108225007_devise_invitable_add_to_users.rb
-rw-r--r-- 1 joel admin 775 Jan 30 21:20 20130130202046_acts_as_taggable_on_migration.rb
-rw-r--r--@ 1 joel admin 422 Feb 5 17:05 20130205154206_create_commissions.rb
-rw-r--r--@ 1 joel admin 266 Feb 7 15:20 20130207133520_add_user_id_to_event_transition.rb
Upvotes: 3
Views: 2155
Reputation: 5268
Ok, the problem is the version number of your letrate migrations. Rails just orders the timestamps in the migration files to know which one was most recently applied. Having 3 more digits in the timestamp, 20121206125016605_create_rates.rb and 20121206125016587_create_rating_caches are always going to be detected as the last migrations.
Let's try to fix it and clean up your migration's status. First rollback the problematic migrations:
rake db:rollback STEP=2
Your rake db:migrate:status
now should look like these:
up 20121205224038 Rename user address column
up 20121210152550 Create reservations
up 20121210180233 Create transactions
up 20121210215840 ********** NO FILE **********
up 20121218144200 Create videos
up 20121218144800 Add video to videos
up 20130108225007 Devise invitable add to users
up 20130130202046 Acts as taggable on migration
up 20130205154206 Create commissions
up 20130207133520 Add user id to event transition
Now let's fix their version number (assuming your migrations are in the default db/migrate
folder)
mv db/migrate/20121206125016605_create_rates.rb db/migrate/20121206125017_create_rates.rb
mv db/migrate/20121206125016587_create_rating_caches.rb db/migrate/20121206125016_create_rating_caches.rb
Now your db:migrate:status
should look like this:
up 20121205224038 Rename user address column
down 20121206125016 Create rating caches
down 20121206125016 Create rates
up 20121210152550 Create reservations
up 20121210180233 Create transactions
up 20121210215840 ********** NO FILE **********
up 20121218144200 Create videos
up 20121218144800 Add video to videos
up 20130108225007 Devise invitable add to users
up 20130130202046 Acts as taggable on migration
up 20130205154206 Create commissions
up 20130207133520 Add user id to event transition
Now the "timeline" is fixed but we still need to reapply those migrations. rake db:migrate
won't work because the last migration is now 20130207133520_add_user_id_to_event_transition.rb and it's been already applied so rake thinks it is up to date... So we have to cheat rake: edit every migration file that appears after 20121206125017_create_rates.rb in the migrate status output by commenting everything inside the down
method. If there's only a change
method, comment it and create empty up and down methods. So all those down methods will be something like this:
def down
# This is the old code
# which I will uncomment later...
end
You also need to create an empty migration because there is a weird migration that has no file associated (the ********** NO FILE **********
one). So create a file named db/migrate/20121210215840_ghost_migration.rb with the following contents:
class GhostMigration < ActiveRecord::Migration
def up
end
def down
end
end
Now we are ready to simulate rolling all the way back. So do
rake db:rollback STEP=9
The migration status output should now be
up 20121205224038 Rename user address column
down 20121206125016 Create rating caches
down 20121206125016 Create ratings
down 20121210152550 Create reservations
down 20121210180233 Create transactions
down 20121210215840 Ghost migration
down 20121218144200 Create videos
down 20121218144800 Add video to videos
down 20130108225007 Devise invitable add to users
down 20130130202046 Acts as taggable on migration
down 20130205154206 Create commissions
down 20130207133520 Add user id to event transition
Now you can change the files back to their original state by uncommenting what you commented before and remove the "Ghost migration" file. You should actually comment the "up" methods the same way we did with the down methods before, remove the "Ghost migration" file and migrate everything
rake db:migrate
Finally uncomment everything you commented out in the files and things should be running smooth after that (I hope).
Regarding why this happened in the first place, I think this is actually due to the gem itself, which in my opinion should not generate those migrations with invalid (or at least non standard) version numbers. It looks like the gem generates two migrations in the same second so maybe the author added those 3 extra digits to prevent version number collision. I think it would have been better to do everything in the same migration.
I hope this helps you to fix your issue!
UPDATE
Maybe I overcomplicated things. If you don't mind actually rolling back all your migrations and then migrating them up again, you don't need to comment anything on any file (the "Ghost migration" trick would still be necessary though). I just felt it would be safer this way.
Upvotes: 6