A developer should never trust users' data and must test every form field before saving them in the database. Fortunately, Ruby on Rails provides several mechanisms that allow you to perform these validations efficiently.
How to validate fields in Ruby on Rails
In most cases, the fields of a form are injected into an ActiveRecord model, which performs the validation. The ActiveRecord::Validations API allows to easily define rules to validate various aspects of these fields: format, inclusion, length, uniqueness, and many others.
Let's take as an example a contact form allowing your visitors to send a message to your staff. Such a form would contain Last and First Name, Email Address, and Message fields. Let's write a model and its validation mechanism to check the presence and length of each field and the email address format. Here is the code:
class ContactData < ApplicationRecord
validates_presence_of :first_name, :last_name, :email, :message
validates_length_of :first_name, :last_name, maximum: 150
validates_format_of :email, with: A_MAGIC_REGEXP
end
ActiveRecord calls all validation methods defined in the model during the saving process. If they are successful, then the model is saved in the database. But if there is at least one error, the model won't be saved in the database. You can then check the content of its errors field to obtain details about the validation errors.
Here are the details of the methods used in the code above:
- validates_presence_of: check that the fields contain something. Note that if the value for this field is a simple space, the validation will succeed.
- validates_length_of: checks the length of the value. The acceptable length of a field depends on the application's needs and the database's field type.
- validates_format_of: checks that the format of the field value matches the regular expression provided in the parameter
While the first two validation methods are easy to understand, the third requires a little more attention.
Validating an email address in Ruby on Rails
The first step of email validation consists of checking the format of the email address. To do this, it is sufficient to use the validates_format_of method mentioned earlier in this document along with an efficient regular expression.
The standard Ruby library provides the URI::MailTo class, which declares the regular expression EMAIL_REGEXP. This is suitable in most cases.
URI::MailTo::EMAIL_REGEXP
=> /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/
Here is how to use it in our model:
class ContactData < ApplicationRecord
validates_presence_of :first_name, :last_name, :email, :message
validates_length_of :first_name, :last_name, maximum: 150
validates_format_of :email, with: URI::MailTo::EMAIL_REGEXP
end
Now that this is done, it is important to understand that validating the format of an email address is not enough. Indeed, the address [email protected], although having a valid format, would certainly not exist. This is why it is necessary to verify not only the format of an email address but also its existence.
Check that an email address exists in Ruby on Rails.
The method for checking the existence of an email address is to extract the server FQDN (the part after the @ sign); to query the corresponding DNS servers to confirm that the server exists; to query the MX records from the DNS entries. A well-made verification method will also match the server name against a list of known disposable email services to determine if the visitor is using a disposable email address.
Setting up such a complex verification method is beyond this document's scope. But fortunately, there is a solution, easy to implement, which we will discuss in the next chapter.
How to efficiently verify and validate an email address in Ruby
Abstract API provides several free services accessible via simple HTTP calls, one of them being email validation. This service verifies email format and queries the DNS records and email servers to verify that the address actually exists. It also checks if the mailbox is a disposable email service.
You will have to create a free account to get your private API key, and then you can implement email validation in your model like this:
class ContactData < ApplicationRecord
validates_presence_of :first_name, :last_name, :email, :message
validates_length_of :first_name, :last_name, maximum: 150
validate :check_email
private def check_email
uri = URI "https://emailvalidation.abstractapi.com/v1/?api_key=#{API_KEY}&email=#{self.email}"
http = Net::HTTP.new uri.host, uri.port
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
request = Net::HTTP::Get.new uri
response = JSON.parse http.request(request)
if ! response['is_valid_format']['value'] || ! response['is_mx_found']['value'] || ! response['is_smtp_valid']['value']
errors.add :email, 'is not valid'
end
end
end
Get your free
Email Validation
key now
See why the best developers build on Abstract
get started for free