- Read Tutorial
- Watch Guide Video
In this lesson, we are going to implement validations for the phone number attribute. To recap, these are the validations we need to integrate:
- No spaces or dashes
- All characters have to be a number
- Numbers need to be exactly 10 characters
Let's open the user_spec.rb
in the models test directory. We'll start by refactoring it a little bit. I'm going to group the test cases for first name, last name and phone number under a different description called validations.
# spec/models/user_spec.rb describe "validations" do it "cannot be created without first_name" do @user.first_name = nil expect(@user).to_not be_valid end it "cannot be created without last_name" do @user.last_name = nil expect(@user).to_not be_valid end it "cannot be created without phone" do @user.phone = nil expect(@user).to_not be_valid end end
With our tests organized, now let's add two more test cases. The first one will confirm that there are only integers in the phone number while the second one is going to check if there are exactly 10 characters. We'll create the tests one at a time.
# spec/models/user_spec.rb it 'requires the phone attr to only contain integers' do @user.phone = 'mygreatstr' expect(@user).to_not be_valid end
In the first test case, I'm setting a string value called "mygreatstr" because if you notice it is 10 characters long. This way, it will not break our next test case, which is going to check for the presence of exactly 10 characters. In fact, I use this string for all phone number validations. Then, we are expecting this value to not be valid.
If you run rspec
, we have one failure as expected.
To fix this, open the user.rb
file in our models
folder. Here, I'm storing the regular expression in a constant called PHONE_REGEX
. If you're unsure of regular expressions, I'd recommend a site called regexpal.com, where you can test out regular expressions. You can also click on a link called cheat sheet or top regular expressions that bring up the most frequently used expressions. In fact, there's one for phone validation, however it's not an exact fit for what we need, but it's nice to have for reference. The reason why it's not a great fit is because it allows spaces, and we don't want spaces in our validation.
So, I'm going to pass a simple regular expression, and this is how it looks:
All that it does is allow only numbers from o to 9, and no other characters.
Let's go back to our user.rb
, paste this regex and call the validates_format_of
method, like this:
# app/models/user.rb PHONE_REGEX = /\A[0-9]*\Z/ validates_format_of :phone, with: PHONE_REGEX
If you run the tests now you'll see that they're passing.
We'll move to the next test case that checks if the phone number has only 10 characters.
# spec/models/user_spec.rb it 'requires the phone attr to only have 10 chars' do @user.phone = '12345678901' expect(@user).to_not be_valid end
After running the tests you'll see that this test fails. In order to implement the validation, go to user.rb
in models
and add this code that checks if the length is exactly 10.
# app/models/user.rb validates :phone, length: { is: 10 }
If you run rspec
, all of the tests are passing.