Skip to content

Migrations failing on 'well' designed tables #5763

Description

@pacMakaveli

I've been using Devise for years and today, for

Image

my migration failed because, well, I designed my table properly..

== TIMESTAMP AddDeviseToUsers: migrating =================================
-- change_table(:users)
bin/rails aborted!
StandardError: An error has occurred, this and all later migrations canceled: (StandardError)

PG::DuplicateColumn: ERROR:  column "email" of relation "users" already exists
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:7:in 'block in AddDeviseToUsers.up'
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:5:in 'AddDeviseToUsers.up'

Caused by:
ActiveRecord::StatementInvalid: PG::DuplicateColumn: ERROR:  column "email" of relation "users" already exists (ActiveRecord::StatementInvalid)
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:7:in 'block in AddDeviseToUsers.up'
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:5:in 'AddDeviseToUsers.up'

Caused by:
PG::DuplicateColumn: ERROR:  column "email" of relation "users" already exists (PG::DuplicateColumn)
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:7:in 'block in AddDeviseToUsers.up'
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:5:in 'AddDeviseToUsers.up'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

and

== TIMESTAMP AddDeviseToUsers: migrating =================================
-- change_table(:users)
   -> 0.0444s
-- add_index(:users, :email, {unique: true})
bin/rails aborted!
StandardError: An error has occurred, this and all later migrations canceled: (StandardError)

PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:39:in 'AddDeviseToUsers.up'

Caused by:
ActiveRecord::StatementInvalid: PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists (ActiveRecord::StatementInvalid)
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:39:in 'AddDeviseToUsers.up'

Caused by:
PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists (PG::DuplicateTable)
/path/to/project/db/migrate/TIMESTAMP_add_devise_to_users.rb:39:in 'AddDeviseToUsers.up'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

It's not that big of a thing as the fix is quite trivial, but I feel like this shouldn't happen in the first place.

My proposed fix would be to add some checks in: lib/generators/active_record/templates/migration_existing.rb

add_index :<%= table_name %>, :email, unique: true, if_not_exists: true

and

<% attributes.each do |attribute| -%>
  t.<%= attribute.type %> :<%= attribute.name %> unless t.column_exists?(attribute)
<% end -%>

Happy to sort a PR for this if we're all in agreement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions