在现有模型上设计迁移

时间:2010-11-14 03:01:40

标签: ruby-on-rails

我正在从Authlogic迁移到Devise。

更新:

设计的迁移尝试重新创建表用户,所以我改变了,你可以看到create_table下面的change_table和删除表,以删除我添加的内容

问题是当我运行rake时出现错误。

这是我在运行rake时遇到的错误。

==  DeviseCreateUsers: 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

这是迁移

class DeviseCreateUsers < ActiveRecord::Migration
  def self.up
    change_table(:users) do |t|
      t.database_authenticatable :null => false
      t.recoverable
      t.rememberable
      t.trackable

      # t.confirmable
      # t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both
      # t.token_authenticatable


      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
    remove_column :users, :database_authenticatable
    remove_column :users, :recoverable
    remove_column :users, :rememberable
    remove_column :users, :trackable
    remove_index :users, :email
    remove_index :users, :reset_password_token
  end
end

在我的schema.rb中,我已经从Authlogic获得了这个。

  create_table "users", :force => true do |t|
    t.string    "username"
    t.string    "email"
    t.string    "crypted_password"
    t.string    "password_salt"
    t.string    "persistence_token"

我认为它看到某种冲突,我无法意识到如何避免那些设计助手

谢谢!

4 个答案:

答案 0 :(得分:22)

您获得的错误是因为您尝试重新创建已有的email字段。 email字段在设计助手t.database_authenticatable中创建。您可以将旧用户表与新系统一起使用,但不需要包含t.database_authenticatable,只需重命名旧字段名称即可。查看Documentation for Devise,您可以看到database_authenticatable只创建了三个字段:email,encrypted_pa​​ssword和password_salt。它们与您在authlogic用户表中已有的email,crypted_pa​​ssword和password_salt相同,因此您可以像这样使用change_table:

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

答案 1 :(得分:4)

您可以在create_table之前添加以下行,而不是将change_table更改为create_table

rename_table :users, :old_users_authlogic

然后,在create_table

之后
say_with_time 'Migrating users from Authlogic to Devise...' do
  execute "INSERT INTO users (id, email, ...) SELECT id, email FROM old_users_authlogic"
end

如果您使用具有参照完整性的索引,请不要忘记将它们更新到新表,因为rename_table会使它们指向old_users_authlogic

答案 2 :(得分:0)

add_column(:users, :database_authenticatable, {:null=>false})

您没有提供有关如何设置此字段的信息。它需要是一个字符串,我想你想传递这些信息。

add_column :users, :database_authenticatable, :string,  :null=>false

有关您获得的错误的更多信息:

undefined method `to_sym'

迁移错误确实令人沮丧,因为它缺少内容,但这意味着您的迁移顺序错误。

例如 - 如果您将一个布尔文件添加到使用模型:

 add_column :users, :user_is_a_jackass, :boolean, :default => false

那将迁移好。但如果你这样做:

add_column :users, :user_is_a_jackass, :default => false

您将收到相同的错误,因为您没有告诉迁移它应该是什么字段类型。

答案 3 :(得分:0)

我通过删除Devise迁移文件解决了这个问题,但没有从Sublime中删除它。然后我做了一个rails g migration remove_email_from_foo,从而删除了email属性。然后我取消了Devise删除迁移文件,该文件在&amp;跑了一个rake db:migrate。设计保存到模型的属性