How to remove index in rails

Ruby on-Rails

Ruby on-Rails Problem Overview


I have found that I have two "survey_id" columns in my schema and that's been causing some problems for me. Specifically I need to remove the second index as I don't want survey_id to be unique.

 add_index "completions", ["survey_id"], name: "index_completions_on_survey_id"
 add_index "completions", ["survey_id"], name: "index_completions_on_survey_id_and_user_id", unique: true

I've tried

def change
   remove_index "completions", ["survey_id"], name => "index_completions_on_survey_id_and_user_id"
 end

and

def change
   remove_index "completions", ["survey_id"], name: "index_completions_on_survey_id_and_user_id"
 end

But neither of those seem to work. What's the correct syntax for this migration to remove the index? I feel like this is basic and I'm just missing something stupid. Thanks in advance!

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

You don't supply the columns in the index when removing one. Try:

remove_index :completions, name: "index_completions_on_survey_id_and_user_id"

Solution 2 - Ruby on-Rails

From rails console, run following

ActiveRecord::Migration.remove_index "completions", name: "index_completions_on_survey_id_and_user_id"

Solution 3 - Ruby on-Rails

You can supply the column name(s) to remove_index. The remove_index method takes table_name and options as parameters. With the options passed in the name of the index is determined via index_name_for_remove private method, which simply does (if it is an array):

...
column_names = Array(options).map(&:to_s)
...

if column_names.any?
  checks << lambda { |i| i.columns.join('_and_') == column_names.join('_and_') }
end

Examples from the API documentation:

Removes the index on branch_id in the accounts table if exactly one such index exists.

remove_index :accounts, :branch_id

Or

remove_index :accounts, column: :branch_id

Removes the index on branch_id and party_id in the accounts table if exactly one such index exists.

remove_index :accounts, column: [:branch_id, :party_id]

Removes the index named by_branch_party in the accounts table.

remove_index :accounts, name: :by_branch_party

Apart from the above, you could just do:

remove_index :accounts, %i[branch_id party_id]

Solution 4 - Ruby on-Rails

The accepted answer here doesn't work when you need to roll back the migration, it will be given ActiveRecord::IrreversibleMigration error.

remove_index is only reversible if given a :column option.

def change
  remove_index "completions", column: [:survey_id], name: "index_completions_on_survey_id_and_user_id"
end

this will remove the index and also reversible.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTom HammondView Question on Stackoverflow
Solution 1 - Ruby on-RailsveeView Answer on Stackoverflow
Solution 2 - Ruby on-RailsDheepakView Answer on Stackoverflow
Solution 3 - Ruby on-RailsSyed AslamView Answer on Stackoverflow
Solution 4 - Ruby on-RailsNaveen KrishnanView Answer on Stackoverflow