Rails 回滚,更改类型并再次迁移

Rails rollback, change type and migrate again

我有一个请求table;

class CreateRequests < ActiveRecord::Migration
  def change
    create_table :requests do |t|
      t.string :from
      t.string :to

      t.timestamps null: false
    end
  end
end

我想用 rake db:rollback STEP = 5 回滚数据库 销毁 Request 模型并创建请求 table with;

t.datetime :from
t.datetime :to

但是,我有一个迁移 table 到 STEP = 2 上的请求模型,

class AddStatusToRequest < ActiveRecord::Migration
  def change
    add_column :requests, :status, :string, :default => "Pending"
  end
end

问题是,如果我销毁 Request table 并使用日期时间类型创建新的 Request table,它会在 STEP = 2 之后创建,而当我 rake db:migrate rails 执行不向请求 table 添加状态列。我该如何克服这个问题?

最好不要在应用迁移后追溯更改迁移,以避免像您所遇到的状态冲突。也许最简单的解决方案是创建一个新的迁移以将类型添加到 requests table,如果列已经存在,则使用守卫不做任何事情:

class AddStatusToRequestIfNotExists < ActiveRecord::Migration
  def change
    unless column_exists? :requests, :status
      add_column :requests, :status, :string, :default => "Pending"
    end
  end
end

编辑

您还需要确保可以从头开始 运行 迁移,因此您可能需要更新现有迁移以防止丢失 table,如下所示:

class AddStatusToRequest < ActiveRecord::Migration
  def change
    unless table_exists? :requests
      add_column :requests, :status, :string, :default => "Pending"
    end
  end
end

不理想,但这可能是最安全的方法。

您可以使用 change_column 创建一个新的迁移来更改列类型:

命令行:rails g migration change_request_to_from_column_types'

新迁移:

class ChangeRequestToFromColumnTypes < ActiveRecord::Migration
  def change
    change_column :requests, :from, :datetime
    change_column :requests, :to, :datetime
  end
end