flyingarmadillo
flyingarmadillo

Reputation: 2139

Rerunning a Migration - Devise Gem

I am developing a rails app and I added the Devise gem to authenticate users. I am now further along with the development and I want to add some of the modules Devise comes packaged with (specifically Confirmable, Lockable, and Token authenticatable). These modules were in the original migrate file commented out. I was wondering if it is possible to simply uncomment these modules and then run "rake db:migrate". Can you rerun a migration like this, or will it break something?

I would have tested this out, but given the work I have put into development, I do not want to break anything at this point. Here is the migration file as it stands:

class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_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
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at

      ## Token authenticatable
      # t.string :authentication_token


      t.timestamps
    end

    add_index :users, :email,                :unique => true
    add_index :users, :reset_password_token, :unique => true
    # add_index :users, :confirmation_token,   :unique => true
    # add_index :users, :unlock_token,         :unique => true
    # add_index :users, :authentication_token, :unique => true
  end
end

Secondly, if I cannot rerun a migration, I realize that I will have to create new migrations and add the modules to the 'Users' model manually. For example:

rails generate migration AddConfirmationToUsers string:confirmation_token datetime:confirmed_at datetime:confirmation_sent_at string:unconfirmed_email

However, I will need to 'add_index' to this new migration just as with the original migration Devise created. Will I just place the 'add_index' at the bottom of the migration (ie, after the 'add_column' method)? Maybe something like this: ?

class AddConfirmableToUsers < ActiveRecord::Migration
  def change
    add_column :users, :price, :decimal
    add_column :users, :confirmation_token, :string
    add_column :users, :confirmed_at, :datetime
    add_column :users, :confirmation_sent_at, :datetime
    add_column :users, :unconfirmed_email, :string

    add_index :users, :confirmation_token,   :unique => true
  end
end

As a recap:

  1. Can I rerun migrations (edit a previous migration and then run 'rake db:migrate')?
  2. If I cannot rerun migrations, where would I place the 'add_index' line in the new migration?

Upvotes: 1

Views: 1520

Answers (1)

Kevin Thompson
Kevin Thompson

Reputation: 2506

You can't just edit the file and run db:migrate. Rails keeps track of which migrations have been run and which have not. Rails thinks that it has already run that migration.

The right thing to do is create a new migration just as you've suggested above.

It sound like you're worried that you're going to trash your database and lose a lot of work. I would suggest that you backup the database before you go forward with this. Database backups and git can help remove a lot of the fear that comes with making changes that you're not sure about.

Upvotes: 3

Related Questions