Ruby on Rails: checking and changing a phone number

I have a simple phone form <%= f.text_field :phone %> right now. :phone is an integer type, so this requires that everything the user enters into the form should be something like 5551234 instead of the more standard method 555-1234 . How can I allow a user to enter a phone number in the USA, for example, what are they used to? I understand that I can use validates_format_of to check it, but as soon as I check it, how can I format the number and insert the phone number in the database as an integer?

+7
validation ruby-on-rails
source share
4 answers

ActiveRecord automatically enters type input based on the type of database column. When Ruby casts a string to an integer, it discards everything after the first non-numeric character, 123-456-7890 will become 123 . This is done before the field is available in the model, so the solutions given so far will not work. You need to overwrite the default recorder!

ActiveRecord :: Base docs mentions two ways to overwrite the default record model (field_name)= in the model so that you can process the input data by removing unnecessary digits before it looks. There are at least three options:

(1) Overwrite the accessory and use write_attribute to save the result in the database:

 def phone=(value) value.gsub!(/\D/, '') if value.is_a?(String) write_attribute(:phone, value.to_i) end 

(2) Or use a hash notation:

 def phone=(num) num.gsub!(/\D/, '') if num.is_a?(String) self[:phone] = num.to_i end 

(3) Or (in recent versions of ActiveRecord) just call super as if it were a regular (non-dynamic) method (not shown in the docs, but works):

 def phone=(num) num.gsub!(/\D/, '') if num.is_a?(String) super(num) end 

This is useful in a number of situations, such as comma numbers, and works great with forms that supply a formatted version of the previous field value, for example, in an edit form or after an error in a new / created form:

 <%= f.text_field :phone, number_to_phone(@model_data.phone) %> 

This way you can display user-formatted data (i.e. as a String), but still store an integer in the database.

Last MySQL tip: you need to use BigInt to store the phone number, otherwise you will see many phone numbers (214) 748-3647 in your database, since 2,147,483,647 is the maximum value of a regular MySQL integer - int(11) is the form received :integer in migration. A BigInt in MySQL is obtained by setting :limit to 8 , as in this migration line:

 change_column :model_name, :phone, :integer, :limit => 8 

This will give you bigint(20) in your table, which can handle numbers up to 9,223,372,036,854,775,807 , which should be enough for any phone number.

+17
source share
 phone.gsub(/\D/, '') 

gotta do the trick. It removes non-digital characters.

+12
source share
 "1-2-3-4".gsub('-','').to_i # => 1234 

You can also use regular expressions if you want to get more fantasies, but you must get away from this.

You probably want to check that you are storing it in the database, because Rails checks the checks before saving. However, you can do before_validation , which changes the number first. Something like that:

 before_validation do phone = phone.to_s.gsub('-','').to_i end 

http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M001378

0
source share

Not sure what you still understand, but I ran into the same problem as Reti with Mark code.

It seems that the specific self.phone = self.phone.gsub(/\D/, '') did the trick.

Maybe because at this moment phone is not yet initialized? I'm not sure, but here is a newbie ...

0
source share

All Articles