Ruby on rails 特定数据库连接上的ActiveRecord迁移可以';t回滚

Ruby on rails 特定数据库连接上的ActiveRecord迁移可以';t回滚,ruby-on-rails,activerecord,migration,rollback,Ruby On Rails,Activerecord,Migration,Rollback,TL;DR-在迁移中使用显式数据库连接会破坏可逆性 我有一个简单的迁移,向特定的数据库连接添加一列:(我的应用程序有几个数据库,理由很充分) 但是,它无法回滚: % be rake db:rollback == 20181120215337 AddFlavorToBikes: reverting ================================= rake aborted! An error has occurred, this and all later migrations

TL;DR-在迁移中使用显式数据库连接会破坏可逆性

我有一个简单的迁移,向特定的数据库连接添加一列:(我的应用程序有几个数据库,理由很充分)

但是,它无法回滚:

% be rake db:rollback
== 20181120215337 AddFlavorToBikes: reverting =================================
rake aborted!
An error has occurred, this and all later migrations canceled:

PG::DuplicateColumn: ERROR:  column "flavor" of relation "bikes" already exists
: ALTER TABLE "bikes" ADD "flavor" character varying/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:5:in `block in change'
/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `tap'
/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `change'
我不明白。db.add_列的回滚应删除该列。那么,为什么我得到一个错误,我试图删除的字段已经存在?它当然存在,这就是为什么我要删除它

我在互联网站上搜索解决方案,甚至是任何有相同问题的人,但没有找到任何线索

我尝试使用显式变量而不是.tap,但得到了相同的错误:

class AddFlavorToBikes < ActiveRecord::Migration
  def change
    db = VehicleBase.connection
    db.add_column :bikes, :flavor, :string
  end
end
class AddFlavorToBikes
ActiveRecord::Migration是我所能识别的最接近的,它失去了检测它是否在默认ActiveRecord::Base连接上向上或向下迁移的能力

因此,它尝试向上迁移
add_column
,即使它正在回滚并且应该向下迁移。因此,它试图再次添加该列,而不是将add\u列反转为remove\u列

这是在Rails 4.2.7和Ruby 2.1.9上实现的


如何使此迁移可逆?

我通过将
change
拆分为
up
down
方法找到了一个合理的解决方案:

class AddFlavorToBikes < ActiveRecord::Migration
  def up
    VehicleBase.connection.tap do |db|
      db.add_column :bikes, :flavor, :string
    end
  end

  def down
    VehicleBase.connection.tap do |db|
      db.remove_column :bikes, :flavor
    end
  end
end
class AddFlavorToBikes

虽然不像可逆迁移那样优雅或枯燥,但这允许db:migrate和db:rollback成功工作。

我通过将
change
拆分为
up
down
方法找到了一个合理的解决方案:

class AddFlavorToBikes < ActiveRecord::Migration
  def up
    VehicleBase.connection.tap do |db|
      db.add_column :bikes, :flavor, :string
    end
  end

  def down
    VehicleBase.connection.tap do |db|
      db.remove_column :bikes, :flavor
    end
  end
end
class AddFlavorToBikes
虽然不像可逆迁移那样优雅或枯燥,但这允许db:migrate和db:rollback成功工作

class AddFlavorToBikes < ActiveRecord::Migration
  def up
    VehicleBase.connection.tap do |db|
      db.add_column :bikes, :flavor, :string
    end
  end

  def down
    VehicleBase.connection.tap do |db|
      db.remove_column :bikes, :flavor
    end
  end
end