Rails 4 Ruby 2.00 Devise migration on existing Use

2019-08-05 08:40发布

问题:

I am trying to add Devise to an Enki based app with Omniauth already implemented and an existing User Model. After following the Devise tutorial on github and trying almost every possible solution posted here or in the Devise wiki, I still cannot get the migration to run.I get this error I get when running rake db:migrate. I am aware that I need to comment out the email column(it exists on the User model). I tried to comment out whichever throwing the 'already exist' error, but that did not work either.

$ rake db:migrate
==  AddDeviseToUsers: migrating ===============================================
-- change_table(:users)
rake aborted!
An error has occurred, this and all later migrations canceled:

PG::DuplicateColumn: ERROR:  column "encrypted_password" of relation "users" already exists
: ALTER TABLE "users" ADD COLUMN "encrypted_password" character varying(255) DEFAULT '' NOT NULL/Users/josecfernandezortiz/.rvm/gems/ruby-2.0.0-p353/gems/activerecord-4.0.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `async_exec'

This is the current schema:

  create_table "users", force: true do |t|
    t.string   "name",           null: false
    t.string   "email",          null: false
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "provider"
    t.string   "uid"
    t.string   "role"
    t.datetime "last_logged_in"
  end

And this is the migration generated by Devise:

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, :null => false
      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, :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


      # Uncomment below if timestamps were not included in your original model.
      # 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
  end

  def self.down
    # By default, we don't want to make any assumption about how to roll back a migration when your
    # model already existed. Please edit below which fields you would like to remove in this migration.
    raise ActiveRecord::IrreversibleMigration
  end
end

I also tried to comment out t.string :encrypted_password, :null => false, :default => "" , same result. Thank you!

回答1:

Your schema.rb file will ONLY contain schema information related to changes made through the migrations of that particular project. So if you added a column OUTSIDE of migrations, schema will not reflect that. I would venture to guess that you might have added Devise OR some/all of those columns used by Devise in a prior project, on a table with the same name.

You could do any of the following:

1) Inspect the User, and confirm if that's the case, and if it is either a) Drop the DB and recreate (I assume there might be other issues/tables/columns you aren't expecting) b) Remove the columns

You can drop and recreate as follows:

rake db:drop db:create db:schema:load