Как сделать remove column обратимым?

у меня есть миграция, которая удаляет столбец:

def change
  remove_column :foos, :bar, :boolean
end

когда я пытаюсь rake db:rollback что миграция, я получаю следующую ошибку:

remove_column is only reversible if given a type.

на И ActiveRecord::Миграция в документации говорится, что следующая подпись для remove_column:

remove_column(table_name, column_name, type, options)

поэтому мой тип в этом случае должен быть :boolean, и я ожидаю, что миграция будет обратимой. Что я упускаю?

Я, конечно, могу разбить это на up и down миграция, чтобы избежать этой проблемы, но я хотел бы понять, почему change синтаксис в этом случае не работает.

2 ответов


просто добавив 3-й аргумент (столбец :type) в remove_column метод делает эту миграцию обратимой. Таким образом, исходный код OP действительно работал, как в:

remove_column :foos, :bar, :boolean

остальная часть этого ответа была попыткой выяснить, почему этот метод не работал, но ОП в конечном итоге заставил его работать.


Я вижу несколько противоположную информацию в документации для И ActiveRecord::Миграция:

некоторые команды типа remove_column не может быть отменено. Если вы хотите определить, как двигаться вверх и вниз в этих случаях, вы должны определить методы вверх и вниз, как и раньше.

список обратимых команд см. В разделе ActiveRecord::Migration:: CommandRecorder.

и ActiveRecord::Migration:: CommandRecorder:

ActiveRecord:: Migration:: CommandRecorder записывает команды, выполненные во время миграция и знает, как отменить эти команды. CommandRecorder знает, как инвертировать следующие команды:

add_column

add_index

add_timestamps

create_table

create_join_table

remove_timestamps

rename_column

rename_index

rename_table

в любом случае, похоже, что это документация устарела... Копаться в источник на github:

метод, который дает вам горе:

def invert_remove_column(args)
  raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
  super
end

Я дал этому выстрел... настройте миграцию на моем приложении Rails 4.1.2, и миграция работала в обоих направлениях - вверх и вниз. Вот моя миграция:

class TestRemoveColumn < ActiveRecord::Migration
  def change
    remove_column :contacts, :test, :boolean
  end
end

Я также пытался с :boolean аргумент отсутствует и получил ту же ошибку, о которой вы говорите. Вы уверены, что находитесь в окончательной версии Rails 4.1.2 -- не один из кандидатов на освобождение? Если вы, я бы предложил положить binding.pry в источник рельсов для invert_remove_column метод для проверки списка аргументов и посмотреть, что происходит. Для этого просто запустите bundle open activerecord а затем исследовать:lib/active_record/миграция / command_recorder.rb: 128.


вместо change, вы используете up и down методы миграции:

def up
  remove_column :foos, :bar
end

def down
  add_column :foos, :bar, :boolean
end