由于我的用户表中的重复列--Rails 3.1,设计rake db:migrate失败

时间:2011-09-17 10:08:50

标签: ruby-on-rails ruby-on-rails-3 devise ruby-on-rails-3.1

这是我第一次安装Devise并运行rake db:migrate时出现的错误:

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

SQLite3::SQLException: duplicate column name: email: ALTER TABLE "users" ADD "email" varchar(255) DEFAULT '' NOT NULL

鉴于这只是测试数据,我可以删除我的数据库中的那个列并重新运行它,但这似乎不是Railsy - 如果只是因为它将使我的登台服务器(唯一)我的应用程序的其他服务器与我的localhost不同步。

此外,如果与另一列发生冲突,该怎么办?

因此,在运行迁移之前,这是我的User表的模式,我该如何处理?迁移某种重命名?

# == Schema Information
#
# Table name: users
#
#  id         :integer         not null, primary key
#  email      :string(255)
#  f_name     :string(255)
#  l_name     :string(255)
#  username   :string(255)
#  role_id    :integer
#  picture    :string(255)
#  about_me   :string(255)
#  website    :string(255)
#  created_at :datetime
#  updated_at :datetime
#

4 个答案:

答案 0 :(得分:17)

在Devise生成的迁移文件中,更改行

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

代表

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

因此,迁移不会尝试创建新的电子邮件列,而是将现有的更改为Devise的规范。

答案 1 :(得分:4)

尝试rake db:rollback,然后重试。当你第一次添加id列时这样做。为什么要在轨道中添加id :integer not null, primary key它是自动的。它应该是这样的:

class CreateProducts < ActiveRecord::Migration
  def up
    create_table :products do |t|
      t.string :email
      t.text :f_name

      t.timestamps
    end
  end

  def down
    drop_table :products
  end
end

您可以在此处获取更多信息http://guides.rubyonrails.org/migrations.html

答案 2 :(得分:3)

解决此错误很简单

  1. 如果您已经运行“rake db:migrate”我建议运行rake db:rollback
  2. 转到“timestamp_add_devise_to_whatever.rb并注释掉
  3. # t.string :email, null: false, default: ""
  4. 接下来还评论此
  5. # add_index :users, :email, unique: true
  6. 运行rake db:migrate,你的好消息。 :)

答案 3 :(得分:2)

我在为现有数据库添加设计时遇到了同样的问题。这为我解决了这个问题:

修改自动生成的设计迁移:

t.rename :email, :email_old   # move my old email field out of the way 
... 
#add_index :users, :email, :unique => true  ## comment out unique index

迁移数据库。

使用SQL调用以交互方式使(新)电子邮件字段数据条目唯一:

update users set email=id;

创建另一个添加唯一约束的迁移,然后运行它:

class UniquifyIndex < ActiveRecord::Migration
  def change
        add_index :users, :email, :unique => true
  end