2010-12-03 2 views
5

J'ai récemment écrit quelques migrations qui tombent sous le parapluie Migration irréversible. Mais ils ne sont pas la fin du monde irréversible. Tu pourrais les renvoyer si tu veux. Le scénario que j'ai en ce moment est en train de changer une relation de un à plusieurs en une relation de plusieurs à plusieurs. Cela implique de déposer une colonne et de créer une nouvelle table de jointure. (ainsi que deux lignes dans les modèles). Je pensais, au lieu d'abandonner la migration vers le bas, je pourrais dire quelque chose comme "Cette migration est [INSÉRER MESSAGE SCARY ICI], êtes-vous sûr de vouloir continuer" Y/N "et ensuite annuler la migration si ils choisissent de? Juste mettre la migration dans une déclaration if?Migrations irréversibles - avertissement et confirmation au lieu d'abandonner?

Il est assez facile de rendre les migrations irréversibles, et il y a généralement de bonnes raisons (par exemple, les données ne peuvent pas être récupérées). Ces problèmes sont-ils généralement résolus en écrivant simplement une migration qui le fait manuellement?

Dans mon esprit noobish ce serait bien d'avoir un juste milieu. Est-ce sage? Peut-être que je ne comprends tout simplement pas quand les rendre non réversibles en premier lieu.

Répondre

1

J'essaie toujours de rendre la migration réversible si possible. La seule fois où je pense avoir rencontré des problèmes, c'est quand on passe d'un modèle de données grossièrement défini à un modèle plus fin, puis à nouveau. Je ne vois aucune raison de ne pas utiliser votre solution bien que, bien sûr, sur les conséquences de la migration. Il n'y a rien qui empêche la personne qui exécute la migration vers le bas de commenter votre erreur déclenchée et d'écrire son propre code pour inverser la migration, mais il est beaucoup plus sûr pour vous, la personne qui écrit le changement de modèle de données de savoir état précédent au lieu de les deviner.

+0

« Il est beaucoup plus sûr pour vous, la personne qui écrit le modèle de données change pour savoir comment revenir à l'état précédent au lieu de deviner ". Exactement! C'est pourquoi j'ai été un peu surpris que cette option ne soit pas déjà disponible - comme il est tout à fait possible que quelqu'un ne fasse que contourner l'exception que vous écrivez. – Nick

+0

Ruby a très peu de règles. Considérez: http://gfredericks.com/gfrlog/post/51 Donc, nous comptons sur le bon sens, la convention, et de bons tests :) –

1

Je viens de trébucher sur ce vieux post ici - comme je me suis battu d'une manière ou d'une autre sur la même question.

J'ai eu l'autre cas: passer de plusieurs-à-plusieurs (HABTM) à un-à-plusieurs. Bien sûr, je voulais supprimer la table de jointure par la suite. J'avais vraiment peur d'oublier de copier les données de la table de jointure lors du déploiement. Je décide donc d'inclure une migration « d'avertissement »:

class DataMigrationWarning < ActiveRecord::Migration 
    def change 

    puts("********************** Data Migration Warning **********************") 
    puts("Dont forgett to save the data.") 
    puts("Next UP migration will delete table XYZ.") 
    puts("Next DOWN migration will delete field A in table BCD.") 
    puts("press y for continue.") 
    puts("press anything else for stopping.") 

    if STDIN.gets.chomp == "y" 
     puts("Ok then!") 
    else 
     fail 
    end 

    # More detailed explanation... 

    end 
end 

La ligne de commande sera alors juste montrer toutes les choses là-bas et attend une entrée de l'utilisateur. Je vais juste aller à la prochaine migration. toutes les autres entrées arrêteront la migration et toutes les suivantes.

Le processus a regardé à la fin comme:

  1. Migration: Créer un nouveau champ pour les nouveaux belong_to
  2. migration d'alerte
  3. Migration: Effacez table de jointure
+0

Exactement ce que je cherchais! Rien de tel qu'un énorme avertissement pour rendre les choses sérieuses. Merci! – Andreas