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.