无法迁移到 heroku(Ruby Rails 教程 [Michael Hartl] 第 10 章)

Can't migrate to heroku (Ruby on Rails tutorial [Michael Hartl] chaper 10)

我正在阅读 Hartl 书的第 10 章。在本章的最后,我们重置了 heroku 数据库,然后进行了迁移。但是当我 运行:

heroku run rails db:migrate

我收到一个错误:

rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedColumn: ERROR:  column "password_digest_string" of relation "users" does not exist
: ALTER TABLE "users" DROP "password_digest_string"

在本教程的前面部分,我删除了一个名为 password_digest_string 的列,因为它的命名不正确而且我还不需要它。似乎 rails 正在尝试再次删除该列,即使它不再存在。我删除了删除此列的迁移文件,但它仍在尝试删除它。同样奇怪的是,自删除该列以来,我已经多次迁移数据库,并且在我重置它之前从未遇到过这个问题。有什么建议吗?

编辑:

这是我的架构文件:

ActiveRecord::Schema.define(version: 20170121224748) do 

  create_table "users", force: :cascade do |t| 
    t.string   "name" 
    t.string   "email" 
    t.datetime "created_at",                      null: false 
    t.datetime "updated_at",                      null: false 
    t.string   "password_digest" 
    t.string   "remember_digest" 
    t.boolean  "admin",           default: false 
    t.index ["email"], name: "index_users_on_email", unique: true 
  end 

end

编辑:

我的迁移是按时间戳顺序进行的。

..._create_users.rb

    class CreateUsers < ActiveRecord::Migration[5.0]
      def change
        create_table :users do |t|
          t.string :name
          t.string :email 

          t.timestamps
        end
      end
    end

..._add_index_to_users_email.rb

    class AddIndexToUsersEmail < ActiveRecord::Migration[5.0]
      def change
        add_index :users, :email, unique: true
      end
    end

..._add_password_digest_to_users.rb

    class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
      def change
        add_column :users, :password_digest, :string
      end
    end

..._remove_columns.rb

    class RemoveColumns < ActiveRecord::Migration[5.0]
      def self.up
        remove_column :users, :password_digest_string
      end
    end

..._add_remember_digest_to_users.rb

    class AddRememberDigestToUsers < ActiveRecord::Migration[5.0]
      def change
        add_column :users, :remember_digest, :string
      end
    end

..._add_admin_to_users.rb

    class AddAdminToUsers < ActiveRecord::Migration[5.0]
      def change
        add_column :users, :admin, :boolean, default: false
      end
    end

$> heroku pg:reset DATABASE 将使 heroku 上的 db:migrate 再次干净

在我看来,AddPasswordDigestToUsers 迁移最初看起来像这样(可能是您拼错了):

class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :password_digest_string
  end
end

然后您意识到该列应该只是 password_digest。因此,您手动将迁移文件编辑为现在的样子,回滚,创建下一个迁移,即 RemoveColumns,然后是 运行 迁移。

现在,当您从头开始迁移时,由于 the way column removal is handled in sqlite,如果您使用 sqlite3(这是您用于开发环境的),将不会出现错误。但是使用Postgres会报错

你应该做的

您应该创建一个迁移来更改列名,而不是您所做的,就像这样:

class RenamePasswordDigestStringColumn < ActiveRecord::Migration[5.0]
  def self.up
    rename_column :users, :password_digest_string, :password_string
  end
end

你现在可以做什么

要在不做太多更改的情况下解决问题,您可以删除 RemoveColumns 迁移(并提交、推送...等等)。那没关系,我认为它不会损害您的生产或开发环境。