Migraciones de rieles: self.up y self.down versus cambio

86

Parece que la nueva versión de rieles tiene métodos de "cambio" versus self.up y self.down.

Entonces, ¿qué sucede cuando uno tiene que revertir una migración? ¿Cómo sabe qué acciones realizar? Tengo el siguiente método que necesito implementar basado en un tutorial en línea:

class AddImageToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :image_file_name, :string
    add_column :users, :image_content_type, :string
    add_column :users, :image_file_size, :integer
    add_column :users, :image_updated_at, :datetime
  end

  def self.down
    remove_column :users, :image_file_name, :string
    remove_column :users, :image_content_type, :string
    remove_column :users, :image_file_size, :integer
    remove_column :users, :image_updated_at, :datetime
  end    
end

¿Cómo puedo hacer lo mismo con el nuevo método de cambio?

rey bandido
fuente

Respuestas:

110

Para muchas operaciones, los rieles pueden adivinar cuál es la operación inversa (sin problemas). Por ejemplo, en su caso, ¿cuál es la operación inversa de add_columnllamar cuando retrocede ? Por supuesto que lo es remove_column. ¿Qué es el inverso de create_table? Es drop_table. Entonces, en estos casos, los rieles saben cómo retroceder y definir un downmétodo es superfluo (puede ver en la documentación los métodos actualmente compatibles con el método de cambio ).

Pero preste atención porque para algún tipo de operación aún necesita definir el downmétodo , por ejemplo, si cambia la precisión de una columna decimal, ¿cómo adivinar la precisión original en la reversión? No es posible, por lo que debe definir el downmétodo.

Como se dijo, le sugiero que lea la Guía de migración de Rails .

Aldo 'xoen' Giambelluca
fuente
33

Es mejor usar Arriba, Abajo, Cambiar:

On Rails 3 (Reversible): que debe agregar una nueva columna hacia arriba y completar todos los registros en la tabla solo hacia arriba, y solo eliminar esta columna hacia abajo

def up
  add_column :users, :location, :string
  User.update_all(location: 'Minsk')
end

def down
  remove_column :users, :location
end

Pero:

Debía evitar usar el método de cambio, lo que permite ahorrar algo de tiempo. Por ejemplo, si no necesita actualizar el valor de la columna inmediatamente después de agregarlo, debe cortar este código para así:

def change
  add_column :users, :location, :string
end

En la parte superior, agregará una columna a la tabla y la eliminará en la parte inferior. Mucho menos código y es una ganancia.

On Rails 4: una forma más útil de escribir lo que necesitamos en un solo lugar:

def change
  add_column :users, :location, :string
  reversible do |direction|
    direction.up { User.update_all(location: 'Minsk') }
  end
end
Kaleem Ullah
fuente
Buena explicación hermano
Bibek Sharma
revirtiendo? también es una buena manera de saber la dirección en la que vas dentro del cambio
baash05
Nada de esto funciona. Solo sigo recibiendo ActiveRecord::IrreversibleMigration.
Throw Away Account
hay situaciones en las que los rieles no logran deshacer la migración. por favor vea su ayuda
Kaleem Ullah
1
class AddImageToUsers < ActiveRecord::Migration
  def change
    add_column :users, :image_file_name, :string
    add_column :users, :image_content_type, :string
    add_column :users, :image_file_size, :integer
    add_column :users, :image_updated_at, :datetime
  end
end
nada-especial-aqui
fuente
Gracias. Pero ¿qué pasaría si retrocedieras? ¿Sabría qué hacer?
banditKing
3
Me quedé dormido. Aldo 'xoen' Giambelluca explica todo.
nada-especial-aquí