Миграция ActiveRecord на конкретное соединение с базой данных не может откат - PullRequest
0 голосов
/ 21 ноября 2018

TL; DR - использование явного подключения к базе данных в процессе миграции нарушает обратимость.

У меня есть простая миграция, добавление столбца к определенному соединению с базой данных: (У моего приложения есть несколько баз данных по уважительным причинам)

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

Это прекрасно работает:

 % be rake db:migrate
== 20181120215337 AddFlavorToBikes: migrating =================================
== 20181120215337 AddFlavorToBikes: migrated (0.0060s) ========================

Однако откат не выполняется:

% 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_column должен удалить столбец.Так почему я получаю сообщение об ошибке, что поле, которое я пытаюсь удалить, уже существует? Конечно, оно существует, поэтому я пытаюсь его удалить.

Я искал решения в Интернете и даже среди тех, у кого была такая же проблема, и не нашел никаких потенциальных клиентов.

Я попытался использовать явную переменную вместо .tap, но получил ту же ошибку:

class AddFlavorToBikes < ActiveRecord::Migration
  def change
    db = VehicleBase.connection
    db.add_column :bikes, :flavor, :string
  end
end

Наиболее близкий, который я смог различить, ActiveRecord :: Migration теряет способностьопределить, перемещается ли он вверх или вниз на любом соединении ActiveRecord :: Base по умолчанию.

Итак, он пытается мигрировать add_column UP, даже если он находится в режиме отката и должен мигрировать вниз.Следовательно, он пытается добавить столбец во второй раз, вместо обращения add_column в remove_column.

Это на Rails 4.2.7 и Ruby 2.1.9

Как я могу сделатьэта миграция обратима?

1 Ответ

0 голосов
/ 21 ноября 2018

Я нашел разумное решение, разделив 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

Хотя это и не так изящно или СУХОЙ, как обратимая миграция, это позволяет db: migrate и db: откат на работу успешно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...