PhoneLib
Phonelib is a gem that validates phone numbers. It can currently perform basic validations and formatting to the e164 international number format and the national number format with prefix. However, it doesn’t contain all of Google’s library functionality.
Table of contents
How to install PhoneLib
Reminder:
Make sure that your containers are up and running.
In your Gemfile, add gem phonelib
.
gem 'phonelib'
Open your terminal within container with docker-compose exec app bash
.
$~/KodaCamp> docker-compose exec app bash
root@0122:/usr/src/app#
Then run bundle install
.
root@0122:/usr/src/app# bundle install
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
...
Installing phonelib 0.7.6
Bundle complete! 24 Gemfile dependencies, 96 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Setup Config
Create an initializer in config/initializers/phonelib.rb
to select the default countries or numerous default countries for processing (country names are ISO 3166-1 Alpha-2 codes):
Phonelib.default_country = 'PH'
To prevent phone number sanitization (keeping digits only)
Phonelib.strict_check = true
Usage
Let’s try it out on our Users pages. Create migration file to add the phone_number
column in users table.
In your terminal, run rails g migration AddPhoneNumberToUsers
to create a migration file.
root@0122:/usr/src/app# rails g migration AddPhoneNumberToUsers
invoke active_record
create db/migrate/xxxxxxxxxxxxxx_add_phone_number_to_users.rb
Edit the migration file
# db/migrate/xxxxxxxxxxxxxx_add_phone_number_to_users.rb
class AddPhoneNumberToUsers < ActiveRecord::Migration[7.0]
def change
add_column :users, :phone_number, :string
end
end
Run rails db:migrate
to create a phone_number
column.
root@0122:/usr/src/app# rails db:migrate
== xxxxxxxxxxxxxx AddPhoneNumberToUsers: migrating ============================
-- add_column(:users, :phone_number, :string)
-> 0.0333s
== xxxxxxxxxxxxxx AddPhoneNumberToUsers: migrated (0.0334s) ===================
ActiveRecord Integration:
This gem includes a validator for the current record. Basic implementation:
# app/models/user.rb
class User < ApplicationRecord
# ...
enum genre: { client: 0, admin: 1 }
+
+ validates :attribute, phone: true
end
This will enable the Phonelib validator for the attribute field. This validator ensures that the value supplied is a legitimate phone number. Please keep in mind that giving a null value also fails.
Additional Options:
# app/models/user.rb
class User < ApplicationRecord
# ...
enum genre: { client: 0, admin: 1 }
- validates :attribute, phone: true
+ validates :phone_number, phone: {
+ possible: true,
+ allow_blank: true,
+ types: %i[voip mobile],
+ countries: [:ph]
+ }
end
possible: true
- allows validation to see whether the provided number is a legitimate phone number (not strict check).
allow_blank: true
- When no value is provided, validation is successful.
types: :mobile
or types: %i[voip mobile]
- allows validation against specified phone type patterns. If matched with possible
, will verify whether a number is viable for the provided type.
countries: [:ph]
- allows validation against specific countries; if mixed with possible, will verify whether the number is viable for the specified countries.
Now, check to see if the Phonelib
is working in the console.
Run rails c
and add a new record to the users database.
With invalid phone_number
root@0122:/usr/src/app# rails c
Loading development environment (Rails 7.0.4)
irb(main):001:0> user = User.client.create(email: 'john.doe@friendly.com', password: 'qwer4321', phone_number: '12121212')
TRANSACTION (0.3ms) BEGIN
User Exists? (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'client1234@friendly.com' LIMIT 1
TRANSACTION (0.4ms) ROLLBACK
=> #<User id: nil, email: "client1234@friendly.com", created_at: nil, updated_at: nil, genre: "client", balance: 0.0, phone_number: "12121212">
irb(main):002:0> user.errors
=> #<ActiveModel::Errors [#<ActiveModel::Error attribute=phone_number, type=invalid, options={:possible=>true, :allow_blank=>true, :types=>[:voip, :mobile], :countries=>[:ph]}>]>
irb(main):003:0>
With valid phone_number
irb(main):002:0> user = User.client.create(email: 'jane.doe@friendly.com', password: 'qwer4321', phone_number: '09163451812')
TRANSACTION (0.4ms) BEGIN
User Exists? (0.5ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'jane.doe@friendly.com' LIMIT 1
User Create (0.4ms) INSERT INTO `users` (`email`, `encrypted_password`, `reset_password_token`, `reset_password_sent_at`, `remember_created_at`, `created_at`, `updated_at`, `genre`, `balance`, `phone_number`) VALUES ('jane.doe@friendly.com', '$2a$12$PgnNvXv80XnyHbZ0M/aaieYt/GrfOgJrCO2cOHBO72nw0c8Bq2LaK', NULL, NULL, NULL, 'xxxx-xx-xx xx:xx:xx.xxxxxxxxx'xxxx-xx-xx xx:xx:xx.xxxxxxxxx0, 0.0, '09163451812')
TRANSACTION (0.9ms) COMMIT
=> #<User id: 12, email: "jane.doe@friendly.com", created_at: "xxxx-xx-xx xx:xx:xx.xxxxxxxxx +0000", updated_at: "xxxx-xx-xx xx:xx:xx.xxxxxxxxx +0000", genre: "client", balance: 0.0, phone_number: "09163451812">
With phone_number
is nil
irb(main):001:0> user = User.client.create(email: 'john.doe@friendly.com', password: 'qwer4321', phone_number: nil)
TRANSACTION (0.3ms) BEGIN
User Exists? (0.3ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'john.doe@friendly.com' LIMIT 1
User Create (1.6ms) INSERT INTO `users` (`email`, `encrypted_password`, `reset_password_token`, `reset_password_sent_at`, `remember_created_at`, `created_at`, `updated_at`, `genre`, `balance`, `phone_number`) VALUES ('john.doe@friendly.com', '$2a$12$5pux0Hab6VOijAhMxNokh.RN7vtyaYZG00j1SE0tpOB2rw99mnMbK', NULL, NULL, NULL, 'xxxx-xx-xx xx:xx:xx.xxxxxxxxx'xxxx-xx-xx xx:xx:xx.xxxxxxxxx0, 0.0, NULL)
TRANSACTION (1.2ms) COMMIT
=> #<User id: 13, email: "john.doe@friendly.com", created_at: "xxxx-xx-xx xx:xx:xx.xxxxxxxxx +0000", updated_at: "xxxx-xx-xx xx:xx:xx.xxxxxxxxx +0000", genre: "client", balance: 0.0, phone_number: nil>
Now we already integrated the Phonelib in our application. You can visit PhoneLib for more information.