Je présume que votre montant en dollars est de type décimal. Ainsi, toute valeur entrée par l'utilisateur dans le champ est transtypée de la chaîne vers le type approprié avant d'être enregistrée dans la base de données. La validation s'applique aux valeurs déjà converties en types numériques, donc regex n'est pas vraiment un filtre de validation approprié dans votre cas.
Vous avez deux possibilités pour résoudre ce problème, cependant:
- Utilisez
validates_numericality_of
. De cette façon, vous laissez la conversion complètement à Rails, et vérifiez simplement si le montant est dans une plage donnée.
- Utilisez la méthode
validate_each
et codez vous-même votre logique de validation (par exemple, vérifiez si la valeur comporte plus de 2 chiffres décimaux).
- Valider la attribute before it's been typecasted:
Ceci est particulièrement utile dans situations de validation où l'utilisateur pourrait fournir une chaîne pour un entier champ et que vous souhaitez afficher la chaîne d'origine retour dans une erreur message. En accédant à l'attribut , la chaîne serait normalement transposée en 0, ce qui n'est pas ce que vous voulez.
Ainsi, dans votre cas, vous devriez pouvoir utiliser:
validates_format_of :amount_before_type_cast, :with => /^[0-9]+\.[0-9]{2}$/, :message => "must contain dollars and cents, seperated by a period"
Notez, cependant, que les utilisateurs pourraient trouver fastidieux de suivre vos règles d'entrée rigides (je préférerais vraiment être en mesure de tapez 500
au lieu de 500.00
, par exemple), et que dans certaines régions, la période n'est pas un séparateur décimal (si vous envisagez d'internationaliser votre application).
Une raison pour laquelle vous n'utilisez pas 'validates_numericality_of' à la place d'une regex? –
Comment utiliser 'validates_numericality_of' pour m'assurer que 500.001 échouerait? Je veux seulement, spécifiquement formaté, '[n'importe quel nombre de 0 à 9 chiffres]. [2 de 0 à 9 chiffres]' - utilisant ainsi 'validates_format_of: amount,: with =>/^ [0-9] + \.[0-9] {2} $ /,: message => "doit contenir des dollars et des cents, séparés par une période" ' –