ruby-on-rails - migrations - rollback migration rails
¿Cómo se puede hacer que remove_column sea reversible? (2)
En lugar de usar el change
, usa up
métodos up
y down
para su migración:
def up
remove_column :foos, :bar
end
def down
add_column :foos, :bar, :boolean
end
Tengo una migración que elimina una columna:
def change
remove_column :foos, :bar, :boolean
end
Cuando intento rake db:rollback
esa migración, aparece el siguiente error:
remove_column is only reversible if given a type.
La documentación de ActiveRecord::Migration dice que la siguiente es la firma de remove_column
:
remove_column(table_name, column_name, type, options)
Entonces mi tipo en este caso debería ser :boolean
, y espero que la migración sea reversible. ¿Qué me estoy perdiendo?
Definitivamente puedo dividir esto en una migración down
up
y down
para evitar este problema, pero me gustaría entender por qué la sintaxis de change
no funciona en este caso.
Simplemente agregando el 3er argumento (el de la columna: tipo) al método remove_column
hace que la migración sea reversible. Entonces, el código original del OP realmente funcionó, como en:
remove_column :foos, :bar, :boolean
El resto de esta respuesta fue un intento de descubrir por qué este método no habría estado funcionando, pero el OP terminó poniéndolo a funcionar.
Veo algo de información contraria en la documentación de ActiveRecord::Migration :
Algunos comandos como remove_column no se pueden revertir. Si le interesa definir cómo moverse hacia arriba y hacia abajo en estos casos, debe definir los métodos arriba y abajo como antes.
Para obtener una lista de comandos que son reversibles, consulte ActiveRecord :: Migration :: CommandRecorder.
Y esto desde ActiveRecord::Migration::CommandRecorder :
ActiveRecord :: Migration :: CommandRecorder registra los comandos realizados durante una migración y sabe cómo invertir esos comandos. El CommandRecorder sabe cómo invertir los siguientes comandos:
añadir columna
add_index
add_timestamps
crear mesa
create_join_table
remove_timestamps
rename_column
rename_index
rename_table
De todos modos, parece que esta documentación está desactualizada ... Indagando en la fuente en github :
El método que te está causando dolor es:
def invert_remove_column(args)
raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
super
end
Le di una oportunidad ... configuré una migración en mi aplicación Rails 4.1.2 y la migración funcionó en ambos sentidos: arriba y abajo. Aquí estaba mi migración:
class TestRemoveColumn < ActiveRecord::Migration
def change
remove_column :contacts, :test, :boolean
end
end
También probé con el argumento :boolean
missing y obtuve el mismo error de lo que estás hablando. ¿Estás seguro de que estás en la versión final de Rails 4.1.2, no es uno de los candidatos para la versión? Si es así, te sugiero que binding.pry
un binding.pry
en el origen de Rails para el método invert_remove_column
para inspeccionar la lista de argumentos y ver qué está pasando. Para hacerlo, simplemente ejecute bundle open activerecord
y luego explore a: lib / active_record / migration / command_recorder.rb: 128 .