2009-12-21 3 views
1

J'ai un modèle d'utilisateur qui vérifie si une valeur a changé before_save (en exécutant User.zipcode_changed?). L'idée est que cela met en file d'attente un travail retardé s'il l'a fait.Où est le bon endroit pour mettre _changed? méthodes dans Rails?

Le problème est, quand j'émigre l'application à partir de zéro, je reçois une erreur:

An error has occurred, all later migrations canceled: 

undefined method `postcode_changed?' for #<User:0x105db6158> 

Par conséquent, où dois-je mettre ces? Le modèle est-il le mauvais endroit?

Répondre

6

Lorsque vous extrayez un nouveau projet à partir de zéro, vous ne devez pas utiliser les migrations pour générer la base de données. Vous devez utiliser rake db:schema:load à la place.

Laissez-moi vous montrer pourquoi. Supposons que vous créez un nouveau modèle Post avec une table de post sur la migration 10. Lors de la migration 11, vous exécutez des élaborations spéciales sur le modèle Post. Après un certain temps, vous décidez de supprimer le modèle Post et la table des postes car ils ne sont plus requis.

Six mois plus tard, vous vérifiez le projet à partir de zéro. Si vous essayez d'exécuter rake db:migrate, la migration 11 échouera à se plaindre du modèle manquant. C'est vrai, le modèle a été retiré plusieurs mois auparavant et il n'est plus disponible. Au lieu de cela, si vous exécutez rake db:schema:load, vous initialisez la base de données avec la bonne version de schéma.

En parlant de migrations, si vous venez de créer la méthode du code postal et que vous essayez d'utiliser le _changed? méthode magique dans la même migration, vous devez recharger le schéma avant.

class MigrationFile < ... 
    self.up 
    add_column :user, :postcode, :string 

    User.all.each { |user| puts user.postcode_changed? } # will fail 

    User.reset_column_information 
    User.all.each { |user| puts user.postcode_changed? } # now it works 
    end 
    ... 
end 
+0

Je devrais probablement souligner que ce code est dans le modèle, pas le contrôleur, mais je vois votre point. –

+0

Je n'ai jamais parlé du contrôleur. –

1

Vous dites les deux zipcode_changed? et postcode_changed? dans votre question. Quel est le nom de la colonne dans votre base de données - code postal ou code postal? ActiveRecord ne créera que le _changed? méthode pratique pour le nom de colonne réel.

0

Ce que vous faites est un code de modèle raisonnable, mais pas si bon dans une migration. L'utilisation de code de modèle dans vos migrations est problématique en raison de problèmes de ce type. Je recommande de coller avec du code orienté SQL.

Questions connexes