Migrações do Rails: self.up e self.down versus change


86

Parece que a nova versão do rails tem os métodos "change" versus self.up e self.down.

Então, o que acontece quando é necessário reverter uma migração, como saber quais ações executar. Tenho o seguinte método que preciso implementar com base em um tutorial online:

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

Como posso fazer o mesmo usando o novo método de alteração?


Respostas:


110

Para muitas operações, os trilhos podem adivinhar qual é a operação inversa (sem problemas). Por exemplo, no seu caso, qual é a operação reversa de add_columnto call quando você faz rollback? Claro que sim remove_column. Qual é o inverso de create_table? É drop_table. Portanto, nesses casos, os rails saber como reverter e definir um downmétodo é supérfluo (você pode ver na documentação os métodos atualmente suportados pelo método de alteração ).

Mas preste atenção porque para algum tipo de operação você ainda precisa definir o downmétodo , por exemplo, se você alterar a precisão de uma coluna decimal, como adivinhar a precisão original no rollback? Não é possível, então você precisa definir o downmétodo.

Como disse, sugiro que você leia o Rails Migrations Guide .


33

Melhor usar Up, Down, Change:

On Rails 3 (Reversível): que deve adicionar nova coluna no up e preencher todos os registros da tabela apenas no up, e apenas excluir esta coluna no down

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

def down
  remove_column :users, :location
end

Mas:

Você teve que evitar usar o método de mudança que permite economizar algum tempo. Por exemplo, se você não precisasse atualizar o valor da coluna imediatamente após sua adição, reduziria este código da seguinte forma:

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

Na parte superior, ele adicionará uma coluna à tabela e a removerá na parte inferior. Muito menos código e é um lucro.

No Rails 4: mais uma maneira útil de escrever o que precisamos em um só lugar:

def change
  add_column :users, :location, :string
  reversible do |direction|
    direction.up { User.update_all(location: 'Minsk') }
  end
end

Boa explicação mano
Bibek Sharma

revertendo? também é uma boa maneira de dizer a direção em que você está indo dentro da mudança
baash05

Nada disso funciona. Eu apenas continuo recebendo ActiveRecord::IrreversibleMigration.
Throw Away Account

há situações em que os trilhos falham na migração de rollback. veja a ajuda
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

Obrigado. Mas o que aconteceria se você retrocedesse. saberia o que fazer?
banditKing

3
Eu dormi demais. Aldo 'xoen' Giambelluca explica tudo.
nada-especial-aqui
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.