How To: Change an already existing table to add devise required columns

buncismamen edited this page Oct 7, 2017 · 8 revisions
Clone this wiki locally

The following migration can be used to add devise required columns to an existing users table.

class AddDeviseToUsers < ActiveRecord::Migration[5.0]
  def change
    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, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.inet     :current_sign_in_ip
      t.inet     :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, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


    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

Devise 2.0 does not provide the migrations helpers

You can see the list of columns generated automatically by Devise here:

Note: it is sometimes easier to just delete the table and re-create it using Devise instead of trying to retrofit Devise into your table.

Adding devise to existing model in the 2.0+ migration schema

You will still have errors in your migration with the 2.0 schema, if you have existing fields such as email.

To eliminate migration errors on duplicate fields, use t.change as shown below.

t.change :email, :string,     :null => false, :default => "" 

Notice that for t.change to work, you have to specify the type for the field being changed. In the case of the email migration above, the email field was of type string.

Modify routes.rb

Don't forget to add following line to your routes.rb.

devise_for :users