2010-12-05 49 views
1

J'ai un peu de mal à normaliser un code de chaîne UPC pour pouvoir le stocker dans le même format dans la base de données.Transformation de données après validation réussie

J'utilise la pierre précieuse ean pour vérifier si la chaîne est bonne (qui fonctionne très bien), mais si je jette un code d'affectation après valide tels que:

validate :upc_check 

def upc_check 
    if !upc.nil? 
     if !upc.ean? 
      errors.add(:upc, 'is not a valid UPC.') 
     else 
      upc = upc.strip 
     end 
    end 
end 

L'appel de bande est juste un exemple car c'est une chaîne. Je vais effectivement supprimer les tirets dans l'upc.

Le code ci-dessus ne fonctionne pas aussi bien car il ne l'enregistre pas réellement. J'ai cherché à déclencher une méthode comme

after_validation :normalize_upc 

def normalize_upc 
    upc = upc.strip 
end 

..mais ce qui précède ne fonctionne pas non plus.

Que faites-vous pour valider et transformer les données après validation?

Répondre

1

Je voudrais faire mon validateur stricte, puis utilisez un filtre before_validation pour effectuer les transformations nécessaires.

+0

Merci, c'est ce que j'ai fini par faire. Ça marche bien. – Nitrodist

1

Je vous recommande de remplacer la méthode de réglage dans votre modèle pour upc et de ne pas avoir une méthode séparée pour la normaliser. Ce serait accompli avec quelque chose comme:

def upc=(value) 
    self.upc = value.strip 
end 

Edit:

Je nettoyais aussi votre méthode de validation pour supprimer cette fonctionnalité comme ceci:

validate :upc_check, :unless => lambda {|m| m.upc.nil?} 

def upc_check 
    errors.add(:upc, 'is not valid') unless upc.ean? 
end 
+0

Merci pour les conseils. J'ai essayé le ci-dessus mais quand j'essaye de le placer de la console, alors il me donne une erreur de «pile de niveau trop profond». Pensées? – Nitrodist

+0

https://gist.github.com/728710 pour un exemple. – Nitrodist

+1

Mon mal va juste continuer à appeler la méthode setter avec ce que j'ai écrit. Changez self.upc en super (value.strip) ou utilisez write_attribute –