Ruby on Rails 5.0升级与迁移用户表冲突

从4.2升级到Rails 5.0后,我收到以下错误:

rails db:migrate == 20160703164716 AddDeviseToUsers: migrating ================================= -- change_table(:users) rails aborted! StandardError: An error has occurred, this and all later migrations canceled: PG::DuplicateColumn: ERROR: column "email" of relation "users" already exists : ALTER TABLE "users" ADD "email" character varying DEFAULT '' NOT NULL /Users/my_username/.rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `async_exec' /Users/my_username/.rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `block in execute' 

阅读以下两个Stack Overflowpost后:

PGError:错误:关系“用户”的列“电子邮件”已存在

在现有模型上设计迁移

我的问题是哪个是解决用户表发生数据库冲突的最佳方法?

是否最好编辑现有的迁移文件,例如20160703164716 AddDeviseToUsers迁移,还是建议进行新的迁移?

在我的开发和基于Heroku的生产环境中,执行新迁移的命令是什么是此迁移的最佳名称,以防止数据库冲突?

 def self.up change_table(:users) do |t| t.recoverable t.trackable # rememberable uses remember_token, but this field is different t.rename :remember_token_expires_at, :remember_created_at # these fields are named differently in devise t.rename :crypted_password, :encrypted_password end end 

以上是第二篇文章中建议的建议代码。

您将如何使用此代码并从中进行新的迁移?

在研究迁移后,我进行了以下迁移:

 rails g migration change_data_type_for_users 

生成我根据我理解的上述错误编辑的新迁移,以建议修复用户字段。 新的迁移代码:

 class ChangeDataTypeForUsers  false, :default => "" end end 

运行rails db:migrate后我收到同样的错误。 我究竟做错了什么? 我现在应该回滚还是编辑新的迁移?

我后来发现了这篇Stack Overflow文章。 ( Rails 4 Ruby 2.00在现有用户模型上设计迁移失败 )这是正确的路径吗? 删除数据库会删除所有数据库数据吗?

另一个发现导致相信如果执行rake db:reset将破坏我的数据库中的数据。 这样做会重新创建数据库吗? 目前尚不清楚,如果所有数据都被销毁,以下post似乎会非常具有破坏性。 我们只想在一个表中修复一个字段。

( rake db:migrate db:reset和db:schema:load之间的区别 )

我真的想回答我自己的问题所以也许这个模型会产生一些差异,这是对似乎由ActiveAdmin创建的用户模型的补充:

 class AdminUser < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable end 

在您的情况下,请记住您正在尝试更改数据库中存在的列,就像您正在创建新列一样。

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

你可以改变那一行

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

在块中,知道“t”是您的用户表