【问题标题】:Devise migration on existing model在现有模型上设计迁移
【发布时间】:2011-05-09 17:25:47
【问题描述】:

我正在从 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"

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

谢谢!

【问题讨论】:

  • 请将 jamuraa 的答案标记为正确。否则,此问题将出现在“未回答的问题列表”中。

标签: ruby-on-rails


【解决方案1】:

我通过删除 Devise 迁移文件而不是从 Sublime 中删除它来解决这个问题。然后我做了一个 rails g migration remove_email_from_foo,从而删除了 email 属性。然后我取消了设计删除迁移文件,该文件重新购买了迁移文件并运行了 rake db:migrate。设计属性保存到模型

【讨论】:

    【解决方案2】:

    你得到的错误是因为你试图重新创建你已经拥有的 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
    

    【讨论】:

    • 能否请您回复或更新原始问题并为其他人提供您的解决方案?
    【解决方案3】:

    您可以在create_table 之前添加以下行,而不是将create_table 更改为change_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

    【讨论】:

      【解决方案4】:
      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
      

      你会得到同样的错误,因为你没有告诉迁移它应该是什么字段类型。

      【讨论】:

      • 感谢您的回答。你说的是真的,但是我意识到最初的迁移使用了设计助手,这就是我认为迁移避免定义类型的原因。我意识到我可以将 create_table 更改为 change_table,我只是更新问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-14
      • 2012-12-26
      • 2021-08-23
      • 2017-03-20
      相关资源
      最近更新 更多