0

I created a migration:

class AddFormCounterToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :form_count, :integer, default: 0
  end
end

I ran rails db:migrate but soon realised I had renamed the column incorrectly. So I ran git reset master --hard -- so that the migration file was removed and schema.rb was reset -- and started again:

class AddFormCounterToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :forms_count, :integer, default: 0
  end
end

But when I ran rails db:migrate this time, not only was the new column created but also the old one.

  t.integer "form_count", default: 0
  t.integer "forms_count", default: 0

Wuh? So I ran rails db:rollback to see if that would work. But that fails with the error: No migration with version number 20181025092233. Since I hadn't committed that file, I believe there isn't a way of restoring it.

Where and why is this migration persisting? What's the best practise when deciding to remove and redo a migration? What's the best way out of this pickle? Is there any way other than running rails db:reset? (I'm using Postgres.)

user3574603
  • 3,364
  • 3
  • 24
  • 59
  • 1
    This is because, the incorrect migration file was already migrated to db and before running rails db:rollback you deleted the old version. If you don't want to reset the db, create a migration with the version number '20181025092233' and exactly same fields, i.e the wrong one. Try rollback again. Then delete the migration and migrate the new one – Rashid D R Oct 25 '18 at 09:54
  • You can also rollback current migration and generate new migration to change column name(https://stackoverflow.com/a/1992045/4650675). – Niraj Kaushal Oct 25 '18 at 09:57

2 Answers2

1

I think you have two solutions here. Either your recreate the exact migration file you destroyed (with the correct timestamp), and you'll be able to rollback from here rails db:rollback and delete it. The schema will be destroyed accordingly.

Another solution: rails hold all the migration it has done in a database table called schema_migrations. When you migrated the database, a corresponding entry in the schema_migrations was created. When you deleted the migration file by reseting on master, you didn't delete that entry in the table. So you can do this:

rails dbconsole

Once in the console

SELECT * FROM schema_migrations;

you'll see all the timestamps from the migrations you made on the database, the one you thought you deleted is here as well. Copy the timestamp and:

DELETE FROM schema_migrations WHERE version=$yourtimestamp;

Quit the db console and reset your database

Vincent Rolea
  • 1,601
  • 1
  • 15
  • 26
  • The migration that was mentioned in the error message wasn't listed in `schema_migrations`. In the end, I went and dropped the database altogether and started again. The correct command for the console is `rails dbconsole`. – user3574603 Oct 25 '18 at 12:26
  • 1
    Good catch fir the command, I updated the answer. True, dropping the database is also the solution if you don't care about loosing the data inside – Vincent Rolea Oct 25 '18 at 14:07
1

First, do a database backup. Then, drop down your database ( rake db:drop ), after this delete your schema.rb and then, start to clean your project

rake db:schema:cache:clear
rake db:schema:cache:dump

Finally create your database again

rake db:create
rake db:migrate

Most of the time, just remove the "schema.rb" to avoid this kind of error. Always maintain the project organization through the console rails commands. Leave Git to control the versions of your application.

Eduardo Rocha
  • 87
  • 1
  • 8