Ruby on Rails: la Validation et la modification d'un numéro de téléphone
J'ai un téléphone simple formulaire <%= f.text_field :phone %>
droit maintenant. :phone
est un type entier, de sorte que ce, quel que soit l'utilisateur dans le formulaire doit être quelque chose comme 5551234
au lieu du plus façon standard de 555-1234
Comment puis-je permettre à l'utilisateur d'entrer dans un états-unis numéro de téléphone comme à leur habitude? Je comprends que je peux utiliser validates_format_of
pour le valider, mais une fois que je valide, comment puis-je formater le nombre et insérez le numéro de téléphone dans l'DB comme un entier?
OriginalL'auteur Reti | 2010-07-30
Vous devez vous connecter pour publier un commentaire.
ActiveRecord automatiquement typecasts en se basant sur les bases de données de la colonne type. Quand Ruby convertit une chaîne en un entier, il tombe tout ce qui est après le premier caractère non numérique,
123-456-7890
deviendra123
. Ceci est fait avant que le champ est disponible dans le modèle, de sorte que les solutions apportées jusqu'à présent ne fonctionnera pas. Vous devez remplacer la valeur par défaut accesseur en écriture!La ActiveRecord::Base docs mentionne deux façons de remplacer l'écriture par défaut accesseur
(field_name)=
dans le modèle, de sorte que vous pouvez traiter l'entrée de retrait de la non-chiffres avant il a besoin d'être catalogué. Il y a au moins trois variantes:(1) Remplacer l'accès et l'utilisation write_attribute stocker le résultat dans la base de données:
(2) Ou de l'utilisation de la valeur de hachage de la notation:
(3) Ou (dans les dernières versions de ActiveRecord) appelez simplement super, comme si c'était normal (non dynamique) méthode (pas indiqué dans les docs mais qui fonctionne):
C'est utile dans un certain nombre de situations telles que les nombres avec des virgules et fonctionne parfaitement avec les formes qui offre une version mise en forme de la précédente valeur de champ dans un formulaire d'édition ou après une erreur dans une nouvelle/créer un formulaire:
De cette façon, vous pouvez montrer à l'utilisateur les données formatées (c'est à dire comme une Chaîne de caractères), mais toujours stocker un nombre entier dans la base de données.
Un dernier conseil sur MySQL: Vous devez utiliser un
BigInt
pour stocker un numéro de téléphone, sinon vous verrez beaucoup de(214) 748-3647
numéros de téléphone dans votre base de données comme2,147,483,647
est la valeur max d'un normal MySQL entier -int(11)
- a obtenu de la forme:integer
dans une migration. UnBigInt
dans MySQL est obtenu par la mise en:limit
à8
comme dans cette migration de la ligne:Cela vous donnera une
bigint(20)
dans votre table qui peut traiter des nombres jusqu'à9,223,372,036,854,775,807
qui devrait être suffisant pour n'importe quel numéro de téléphone.+1 pour l'Int/BigInt point. Je n'ai jamais pensé que, si (pour le meilleur ou pour le pire), en général, je stocke mes numéros de téléphone des chaînes de caractères.
OriginalL'auteur Niels
devrait faire l'affaire. Il supprime chiffre caractères.
before_validation do; phone = phone.to_s.gsub(/\D/, '').to_i; end
Dans mon modèle.rb fichier, mais il n'est toujours pas changer quoi que ce soit.L'expression régulière marche pour moi dans la cisr, Ruby 1.8.7:
"(213) 456-7890".gsub(/\D/,'') => "2134567890"
Il y a un certain nombre de méthodes pour obtenir l'entier formaté pour afficher un numéro de téléphone. Voir NumberHelper (api.rubyonrails.org/classes/ActionView/Helpers/...) ou le "téléphone" gem (github.com/carr/phone)
Comme mentionné ci-dessous par Josh, vous devez dire:
ruby self.phone = phone.gsub(...)
Vous devez utiliser l'option "auto" lorsque vous êtes à la mise à jour d'un enregistrement actif de terrain; sinon ruby suppose que vous êtes juste en paramètre une variable locale.OriginalL'auteur Mark Thomas
Vous pouvez également utiliser des Expressions Régulières si vous souhaitez obtenir plus de fantaisie, mais vous devriez être en mesure de s'en tirer avec juste cette.
Vous voulez probablement pour valider ce que vous êtes de les stocker dans la base de données, depuis les Rails de contrôles des validations avant de l'enregistrer. Cependant, vous pouvez faire un
before_validation
qui modifie le nombre premier. Quelque chose comme ceci:http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M001378
(123)555-1234
ou123-555-1234
ou(123) 555-1234
, etc. Donc cette méthode n'est pas tout à fait obtenir tout.Dans ce cas vous pouvez utiliser les RegEx, qui sont de plus en plus puissants. Marque de l'exemple dans sa réponse fonctionne à merveille.
OriginalL'auteur Karl
Vous ne savez pas si vous avez obtenu ce compris, mais j'ai rencontré le même problème que Reti fait avec Mark code.
Il semble que spécifique
self.phone = self.phone.gsub(/\D/, '')
a fait le tour.C'est peut-être parce qu'à ce point de
phone
n'est pas encore initialisé? Je ne suis pas sûr, encore un newbie...OriginalL'auteur Josiah