Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AddClearanceToUsers down method (remove_index) #931

Merged
merged 2 commits into from May 7, 2021

Conversation

Spone
Copy link
Contributor

@Spone Spone commented Feb 12, 2021

Currently, the self.down method of the AddClearanceToUsers migration only removes the columns, but not the indexes.

So if you migrate and then rollback, you can no longer migrate:

rails db:migrate 
== 20210212135500 AddClearanceToUsers: migrating ==============================
-- change_table(:users)
   -> 0.0212s
-- add_index(:users, :email)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists
/home/hans/projects/dummy/db/migrate/20210212135500_add_clearance_to_users.rb:9:in `up'
/home/hans/projects/dummy/bin/rails:9:in `<top (required)>'
/home/hans/projects/dummy/bin/spring:15:in `<top (required)>'

Caused by:
ActiveRecord::StatementInvalid: PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists
/home/hans/projects/dummy/db/migrate/20210212135500_add_clearance_to_users.rb:9:in `up'
/home/hans/projects/dummy/bin/rails:9:in `<top (required)>'
/home/hans/projects/dummy/bin/spring:15:in `<top (required)>'

Caused by:
PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists
/home/hans/projects/dummy/db/migrate/20210212135500_add_clearance_to_users.rb:9:in `up'
/home/hans/projects/dummy/bin/rails:9:in `<top (required)>'
/home/hans/projects/dummy/bin/spring:15:in `<top (required)>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

This fix adds the remove_index calls to the self.down method.

@Spone Spone changed the title FIx AddClearanceToUsers down method (remove_index) Fix AddClearanceToUsers down method (remove_index) Feb 12, 2021
@gnfisher
Copy link
Contributor

gnfisher commented Mar 14, 2021

Thank you for opening this PR @Spone!

I tried to reproduce this and failed. I set up a test rails app with sqlite and postgresql and:

  • Installed clearance
  • Ran the generator script
  • Rolledback
  • Migrated again

This completed successfully:

~/Code/thoughtbot/clearance_test main*
❯ bin/rails db:migrate
== 20210314172157 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0016s
-- add_index(:users, :email)
   -> 0.0010s
-- add_index(:users, :remember_token)
   -> 0.0006s
== 20210314172157 CreateUsers: migrated (0.0032s) =============================


~/Code/thoughtbot/clearance_test main*
❯ bin/rails db:rollback
== 20210314172157 CreateUsers: reverting ======================================
-- remove_index(:users, :remember_token)
   -> 0.0020s
-- remove_index(:users, :email)
   -> 0.0009s
-- drop_table(:users)
   -> 0.0007s
== 20210314172157 CreateUsers: reverted (0.0061s) =============================


~/Code/thoughtbot/clearance_test main*
❯ bin/rails db:migrate
== 20210314172157 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0016s
-- add_index(:users, :email)
   -> 0.0008s
-- add_index(:users, :remember_token)
   -> 0.0007s
== 20210314172157 CreateUsers: migrated (0.0032s) =============================

Could you share more details about your configuration to help me reproduce this issue?

Thanks!

@MottiniMauro
Copy link
Contributor

@Spone Which database and Rails version are you using? I think that before rails 4 removing the column would not necessarily remove the index

@Spone
Copy link
Contributor Author

Spone commented Apr 12, 2021

Hi, sorry for the delay. I'm using Postgres with Rails 6.1.3.1.

My users table primary key is a uuid, and I think it may be the cause of the issue.

I managed to reproduce the issue on a fresh Rails install.

Create this migration:

class CreateUsers < ActiveRecord::Migration[6.1]
  def change
    enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')

    create_table :users, id: :uuid, default: 'gen_random_uuid()' do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end

Then run:

$ rails generate clearance:install
[...]
$ rails db:migrate  
== 20210412221117 CreateUsers: migrating ======================================
-- extension_enabled?("pgcrypto")
   -> 0.0025s
-- create_table(:users, {:id=>:uuid, :default=>"gen_random_uuid()"})
   -> 0.0166s
== 20210412221117 CreateUsers: migrated (0.0194s) =============================

== 20210412221137 AddClearanceToUsers: migrating ==============================
-- change_table(:users)
   -> 0.0066s
-- add_index(:users, :email)
   -> 0.0034s
-- add_index(:users, :remember_token)
   -> 0.0100s
-- select_all("SELECT id FROM users WHERE remember_token IS NULL")
   -> 0.0037s
== 20210412221137 AddClearanceToUsers: migrated (0.0241s) =====================
$ rails db:rollback
== 20210412221137 AddClearanceToUsers: reverting ==============================
-- change_table(:users)
   -> 0.0033s
== 20210412221137 AddClearanceToUsers: reverted (0.0034s) =====================
$ rails db:migrate 
== 20210412221137 AddClearanceToUsers: migrating ==============================
-- change_table(:users)
   -> 0.0053s
-- add_index(:users, :email)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists
/home/hans/projects/sandbox/debug_clearance/db/migrate/20210412221137_add_clearance_to_users.rb:9:in `up'
/home/hans/projects/sandbox/debug_clearance/bin/rails:5:in `<top (required)>'
/home/hans/projects/sandbox/debug_clearance/bin/spring:10:in `block in <top (required)>'
/home/hans/projects/sandbox/debug_clearance/bin/spring:7:in `tap'
/home/hans/projects/sandbox/debug_clearance/bin/spring:7:in `<top (required)>'

Caused by:
ActiveRecord::StatementInvalid: PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists
/home/hans/projects/sandbox/debug_clearance/db/migrate/20210412221137_add_clearance_to_users.rb:9:in `up'
/home/hans/projects/sandbox/debug_clearance/bin/rails:5:in `<top (required)>'
/home/hans/projects/sandbox/debug_clearance/bin/spring:10:in `block in <top (required)>'
/home/hans/projects/sandbox/debug_clearance/bin/spring:7:in `tap'
/home/hans/projects/sandbox/debug_clearance/bin/spring:7:in `<top (required)>'

Caused by:
PG::DuplicateTable: ERROR:  relation "index_users_on_email" already exists
/home/hans/projects/sandbox/debug_clearance/db/migrate/20210412221137_add_clearance_to_users.rb:9:in `up'
/home/hans/projects/sandbox/debug_clearance/bin/rails:5:in `<top (required)>'
/home/hans/projects/sandbox/debug_clearance/bin/spring:10:in `block in <top (required)>'
/home/hans/projects/sandbox/debug_clearance/bin/spring:7:in `tap'
/home/hans/projects/sandbox/debug_clearance/bin/spring:7:in `<top (required)>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

@MottiniMauro
Copy link
Contributor

After investigating this it seems that the cause of the issue is that your CreateUsers migration does not add an index to the email column, so the migration that clearance creates adds it on up but it's then not removed on down. The other index we add is remember_token, but that one doesn't cause an issue because we are also adding/removing the column.

I think your proposed changes would fix this, but I want to take some time to make sure there won't be any side effects to this before merging it.

@MottiniMauro
Copy link
Contributor

Merging this. Thanks for your contribution @Spone!

@MottiniMauro MottiniMauro merged commit 6a284cc into thoughtbot:master May 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants