Migrations Rails: self.up et self.down contre changement

86

On dirait que la nouvelle version des rails a des méthodes de «changement» par rapport aux méthodes self.up et self.down.

Alors, que se passe-t-il quand 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?

banditKing
la source

Réponses:

110

Pour de nombreuses opérations, les rails peuvent deviner quelle est l'opération inverse (sans problème). Par exemple, dans votre cas, quelle est l'opération inverse add_columnpour appeler lors de la restauration? Bien sûr que c'est remove_column. Quel est l'inverse de create_table? C'est drop_table. Donc, dans ces cas, les rails savent comment revenir en arrière et définir une downméthode est superflu (vous pouvez voir dans la documentation les méthodes actuellement supportées par la méthode de changement ).

Mais faites attention car pour un type d'opération, vous devez toujours définir la downméthode , par exemple si vous modifiez la précision d'une colonne décimale, comment deviner la précision d'origine lors de la restauration? Ce n'est pas possible, vous devez donc définir la downméthode.

Comme dit, je vous suggère de lire le guide des migrations Rails .

Aldo 'xoen' Giambelluca
la source
33

Mieux vaut utiliser Up, Down, Change:

Sur les rails 3 (réversible): qui devrait ajouter une nouvelle colonne en haut et remplir tous les enregistrements du tableau uniquement en haut, et ne supprimer cette colonne qu'en 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'avez pas besoin de mettre à jour la valeur de la colonne immédiatement après son ajout, vous réduirez ce code pour ressembler à ceci:

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

En haut, il ajoutera une colonne à la table et la supprimera en bas. Beaucoup moins de code et c'est un profit.

On Rails 4: un autre moyen 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
Kaleem Ullah
la source
Belle explication bro
Bibek Sharma
revenant? est également un bon moyen de dire la direction dans laquelle vous allez à l'intérieur du changement
baash05
Rien de tout cela ne fonctionne. Je continue juste à avoir ActiveRecord::IrreversibleMigration.
Compte à jeter
il existe des situations dans lesquelles les rails ne parviennent pas à annuler la migration. s'il vous plaît voir leur aide
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
rien de spécial ici
la source
Merci, mais que se passerait-il si vous reveniez en arrière. saurait-il quoi faire?
banditKing
3
J'ai trop dormi. Aldo 'xoen' Giambelluca explique tout.
rien de spécial-ici