web-dev-qa-db-fra.com

Rails migrations: self.up et self.down versus change

On dirait que la nouvelle version Rails a "change" par rapport aux méthodes self.up et self.down.

Alors, que se passe-t-il lorsque l'on doit annuler une migration comment sait-il quelles actions effectuer. J'ai la méthode suivante que je dois implémenter sur la base d'un tutoriel en ligne:

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

Comment puis-je faire de même en utilisant la nouvelle méthode de changement?

82
banditKing

Pour de nombreuses opérations Rails peut deviner quelle est l'opération inverse (sans problème). Par exemple, dans votre cas, quelle est l'opération inverse de add_column pour appeler lorsque vous annulez? Bien sûr, c'est remove_column. Quel est l'inverse de create_table? C'est drop_table. Donc dans ces cas Rails savoir comment restaurer et définir une méthode down est superflu (vous pouvez voir dans la documentation les méthodes actuellement supportées par la méthode change) ).

Mais faites attention parce que pour une sorte d'opération, vous devez toujours définir la méthode down, par exemple si vous changez la précision d'une colonne décimale comment deviner la précision d'origine sur rollback? Ce n'est pas possible, vous devez donc définir la méthode down.

Comme dit, je vous suggère de lire le Rails Migrations Guide .

109

Mieux vaut utiliser Up, Down, Change:

On Rails 3 (Reversible): qui devrait ajouter une nouvelle colonne vers le haut et remplir tous les enregistrements du tableau uniquement vers le haut, et ne supprimer cette colonne que vers le bas

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

def down
  remove_column :users, :location
end

Mais:

Il fallait éviter d'utiliser la méthode de changement qui permet de gagner du temps. Par exemple, si vous n'aviez pas besoin de mettre à jour la valeur de la colonne immédiatement après son ajout, vous réduiriez ce code comme ceci:

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

En haut, il ajoutera une colonne au tableau et le supprimera en bas. Beaucoup moins de code et c'est un profit.

On Rails 4: une autre façon utile d'écrire ce dont nous avons besoin en un seul endroit:

def change
  add_column :users, :location, :string
  reversible do |direction|
    direction.up { User.update_all(location: 'Minsk') }
  end
end
30
Kaleem Ullah
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
1