Last active
October 7, 2021 13:59
-
-
Save jcypret/df1b7987969d4ed3f9c8dabc8f1df8e0 to your computer and use it in GitHub Desktop.
Phone normalization in Rails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/business.rb | |
class Business < ApplicationRecord | |
attribute :phone, PhoneType.new | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gem "phonelib" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/initializers/phone_lib.rb | |
Phonelib.default_country = "US" | |
Phonelib.extension_separate_symbols = ["x", ";"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PhoneType < ActiveRecord::Type::String | |
# store values in DB using the E.164 standard | |
# | |
# Examples: | |
# US: +15012223333 | |
# US w/ extension: +15012223333;44 | |
# International: +447911123456 | |
# | |
def serialize(value) | |
if value.present? | |
parsed_phone = Phonelib.parse(value) | |
return super(value.to_s.strip.presence) unless parsed_phone.valid? | |
super(parsed_phone.full_e164) | |
else | |
super(nil) | |
end | |
end | |
# format values to human readable | |
# | |
# Examples: | |
# US: (501) 222-3333 | |
# US w/ extension: (501) 222-3333 x44 | |
# International: +44 791 112 3456 | |
# | |
def deserialize(value) | |
parsed_phone = Phonelib.parse(value) | |
return value unless parsed_phone.valid? | |
formatted_phone = | |
if parsed_phone.country == "US" | |
parsed_phone.full_national | |
else | |
parsed_phone.full_international | |
end | |
# format E.164 extension separator as friendlier "x123" | |
formatted_phone.gsub!(";", " x") | |
formatted_phone | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment