I'm in the process of adding Devise to an existing Rails app, with a Users table already defined. The devise generator pushed out the following migration:
class AddDeviseToUsers < ActiveRecord::Migration
def self.up
change_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
blah blah blah....
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
end
The downward migration isn't generated, and I'm having a heck of a time removing those indexes. I'm seeing different suggested notation in the documentation, and different suggestions online, but none of them seem to be working for me. For example...
def self.down
change_table(:users) do |t|
t.remove :email
t.remove :encrypted_password
t.remove :reset_password_token
blah blah blah...
end
remove_index :users, :email
remove_index :users, :reset_password_token
end
results in...
An error has occurred, this and all later migrations canceled:
Index name 'index_users_on_email' on table 'users' does not exist
which is odd, because if I check the database, sure enough, 'index_users_on_email' is right there...
I've tried other variations, including
remove_index :users, :column => :email
remove_index :users, 'email'
or:
change_table(:users) do |t|
t.remove_index :email
end
...but no dice. I'm running Rails 3.1.0, Ruby 1.9.2, rake 0.9.2.2, with Postgres.
The command that's letting me down is:
bundle exec rake db:rollback STEP=1
after successfully apply the migration up. Any advice?
You can also remove the index specifying the columns, which from my point of view is less error prone than writing the name
Here is my full run of this(in Rails 5):
I have team_id as an index in table vendors. I no longer need this relation. To get rid of it. Did the following:
1) create the migration.
2) Running the migration, give me this error. And that is because vendor table has rows whose foreign key references the primary key value of the team table
3) To solve this and get the migration running, I did the following(Note: i am in dev):
For the record, the way to remove an index by name is
so in your case
To alter a table and/or its indeces use
#change_table
inside#change
action of a migration. Then you be able to create reversable index removal as follows:When you have to drop a table with its index of course with reversable action you can use
#drop_table
method forSchemaStatements
with the#index
method ofTable
class forConnectionAdapter
:In case you have need exactly the
#up/down
pair in a migration. Use just a#change_table
method along with#remove_index
method ofTable
class forConnectionAdapter
:All of the methods are available in
Rails
version of2.1.0
or of earlier ones.Depending on the database type, you don't need to worry about removing the indexes in the
self.down
method since the index will automatically be removed from the database when you drop the column.You can also use this syntax in your
self.down
method:I'd like to expand on @iWasRobbed's answer. If you have index on just single column then worrying about
remove_index
doesn't make sense since (just an assumtion!) the DB should be smart enough to cleanup the resources used by that index. But in case you have multiple columns index removing the column will reduce index to still existing columns, which is totally sensible thing to do, but kind of shows where you might want to useremove_index
explicitely.Just for illustration - migration below has that flaw that after being applied up and down it will leave the unique index on
email
(meaning thedown
part is not doing its job properly)Changing the
down
block towill fix that flaw and allow the migration to correctly return DB to the previous state with
rake db:rollback