Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot remove an index from table in Rails 4 and PSQL 9.3

In my schema.rb I have the following line:

add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree

When I run \di in psql I get:

Schema |                             Name                             | Type  | Owner |         Table
--------+--------------------------------------------------------------+-------+-------+-----------------------
 public | index_users_on_email                                         | index | alex  | users

Yet, if I include in a migration one of these:

  • remove_index :users, name: :index_users_on_email
  • remove_index :users, column: :email
  • remove_index :users, :email
  • execute 'DROP INDEX index_users_on_email'

I get the following error:

rake aborted!
An error has occurred, this and all later migrations canceled:

Index name 'index_users_on_email' on table 'users' does not exist

I also found this issue. So any ideas?

like image 501
Alexander Popov Avatar asked Oct 22 '13 14:10

Alexander Popov


3 Answers

I know this is coming very late, but I just ran into something similar. Is there any chance you're renamed the 'email' column before you tried to remove the index? If so, by renaming the column, the index is getting removed. So the order would have to be:

1) remove index 2) rename column

like image 50
loganhasson Avatar answered Oct 23 '22 19:10

loganhasson


If you want to remove an index by name you could write it like this:

remove_index(:table_name, :name => 'index_name')

You should look at this question as well: What's the correct syntax for remove_index in a Rails 3.1.0 migration?

like image 24
ChrisBarthol Avatar answered Oct 23 '22 17:10

ChrisBarthol


A bit of a late answer, but I just ran into the same issue so I am writing this answer in the hopes it will help others in the future.

The issue that the original asker ran into led to the solution. It appears that in Rails 3.x, the implementation of index_name_for_remove was flawed so that it sometimes did not accept named indexes. Instead, it raised an ArgumentError claiming the index does not exist.

In Rails 4.x, the implementation was changed so that passing a hash with the index name was handled correctly (I think, I do not have a Rails 4 app at the moment to test with).

If you need to handle this in Rails 3.x, looking at the source of remove index leads to the solution - using the remove_index! method. remove_index! takes two arguments - the table name and the index name. So in the case of the original poster's question, this command should do the job:

remove_index! :users, :index_users_on_email

Update: After posting the answer I noticed that the original poster was asking about Rails 4, so it would seem that in certain cases there are still problems with the implementation of index_name_for_remove not detecting the correct index name. However, since the name of the index is known and we don't need to actually find out what the name is (which is what index_name_for_remove does internally), we can still use the remove_index! method to remove it.

like image 2
tbrisker Avatar answered Oct 23 '22 17:10

tbrisker