references rails migrations create ruby-on-rails rails-migrations

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 .