James Hong
James Hong

Reputation: 41

Add column in Rails 5.1 migration not rolling back properly

this is my first question here so please be kind. I recently ran into this issue. A migration for adding a column is not rolling back properly. I can always do this with SQL statements, but I really wanted to figure out why this was not working.

My migration code looks like this.

class ChangeTypeForColumnStatusForInvoices < ActiveRecord::Migration[5.1]
  add_column :invoices, :tutor_pay, :integer
  remove_column :invoices, :status, :integer
  add_column :invoices, :status, :string
end

Here is the migration and the rollback when executed.

jameshong ~/Projects/tad_is_my_boss/toptutoring $ rails db:migrate
W, [2017-08-01T23:43:38.664232 #5782]  WARN -- : [SKYLIGHT] [1.3.1] Running Skylight in development mode. No data will be reported until you deploy your app.
(To disable this message for all local apps, run `skylight disable_dev_warning`.)
-- add_column(:invoices, :tutor_pay, :integer)
   -> 0.0030s
-- remove_column(:invoices, :status, :integer)
   -> 0.0015s
-- add_column(:invoices, :status, :string)
   -> 0.0011s
== 20170801015229 ChangeTypeForColumnStatusForInvoices: migrating =============
== 20170801015229 ChangeTypeForColumnStatusForInvoices: migrated (0.0000s) ====

jameshong ~/Projects/tad_is_my_boss/toptutoring $ rails db:rollback
W, [2017-08-01T23:44:00.076660 #5821]  WARN -- : [SKYLIGHT] [1.3.1] Running Skylight in development mode. No data will be reported until you deploy your app.
(To disable this message for all local apps, run `skylight disable_dev_warning`.)
-- add_column(:invoices, :tutor_pay, :integer)
-- add_column(:invoices, :tutor_pay, :integer)
rails aborted!
ActiveRecord::StatementInvalid: PG::DuplicateColumn: ERROR:  column "tutor_pay" of relation "invoices" already exists
: ALTER TABLE "invoices" ADD "tutor_pay" integer
/Users/jameshong/Projects/tad_is_my_boss/toptutoring/db/migrate/20170801015229_change_type_for_column_status_for_invoices.rb:2:in `<class:ChangeTypeForColumnStatusForInvoices>'
/Users/jameshong/Projects/tad_is_my_boss/toptutoring/db/migrate/20170801015229_change_type_for_column_status_for_invoices.rb:1:in `<top (required)>'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
PG::DuplicateColumn: ERROR:  column "tutor_pay" of relation "invoices" already exists
/Users/jameshong/Projects/tad_is_my_boss/toptutoring/db/migrate/20170801015229_change_type_for_column_status_for_invoices.rb:2:in `<class:ChangeTypeForColumnStatusForInvoices>'
/Users/jameshong/Projects/tad_is_my_boss/toptutoring/db/migrate/20170801015229_change_type_for_column_status_for_invoices.rb:1:in `<top (required)>'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
ActiveRecord::StatementInvalid: PG::DuplicateColumn: ERROR:  column "tutor_pay" of relation "invoices" already exists
: ALTER TABLE "invoices" ADD "tutor_pay" integer
/Users/jameshong/Projects/tad_is_my_boss/toptutoring/db/migrate/20170801015229_change_type_for_column_status_for_invoices.rb:2:in `<class:ChangeTypeForColumnStatusForInvoices>'
/Users/jameshong/Projects/tad_is_my_boss/toptutoring/db/migrate/20170801015229_change_type_for_column_status_for_invoices.rb:1:in `<top (required)>'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
PG::DuplicateColumn: ERROR:  column "tutor_pay" of relation "invoices" already exists
/Users/jameshong/Projects/tad_is_my_boss/toptutoring/db/migrate/20170801015229_change_type_for_column_status_for_invoices.rb:2:in `<class:ChangeTypeForColumnStatusForInvoices>'
/Users/jameshong/Projects/tad_is_my_boss/toptutoring/db/migrate/20170801015229_change_type_for_column_status_for_invoices.rb:1:in `<top (required)>'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:rollback
(See full trace by running task with --trace)

As you can see, The migration properly adds column tutor_pay to relation invoices. However, when I rollback, the SQL that is performed is ADD COLUMN instead of DROP COLUMN. According to the rails guide, add_column is supposed to be a reversable migration. I've tried using change table instead. And I still get the same issue.

Would greatly appreciate it if someone could help me figure this out.

Upvotes: 1

Views: 779

Answers (2)

Chakreshwar Sharma
Chakreshwar Sharma

Reputation: 2610

Use the below migration:

class ChangeTypeForColumnStatusForInvoices < ActiveRecord::Migration[5.1]
  def change
    add_column :invoices, :tutor_pay, :integer
      remove_column :invoices, :status, :integer
      add_column :invoices, :status, :string
    end
  end
end

Or you can also create self.up block for executing migration & self.down block for rollback for more info

Upvotes: 3

James Hong
James Hong

Reputation: 41

I probably needed some sleep.

Didn't realize that I had to wrap all of this in a change method.

class ChangeTypeForColumnStatusForInvoices < ActiveRecord::Migration[5.1]
  def change      
    add_column :invoices, :tutor_pay, :integer
    remove_column :invoices, :status, :integer
    add_column :invoices, :status, :string
  end
end

Upvotes: 0

Related Questions