Rails Model Validators

When developing a Ruby on Rails web application it is a good idea to use ActiveRecord validators to insure the state of a record before posting it to the database. To flush out this example I present the following model:

class User < ActiveRecord::Base
  validates_uniqueness_of :username
  validates_presence_of :username, :password, :email
  validates_size_of :username, :password, :within => 5..15
  validates_format_of :email,
    :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  validates_format_of :username, :with => /^\w+$/i,
    :message => "can only contain letters and numbers."
  validates_confirmation_of :password
  validates_inclusion_of :gender, :in => %w(male female)
  validates_acceptance_of :eula
end

This class models a user in a rails application. The application would normally have a user registration page and a login page. These user validations are checked when trying to save the model into the database but most of them support a :on options that accepts either the :save, :create, or :update values.

Let me now walk through each validation. The validates_uniqueness_of method ensures that the named attribute is unique in the system. In this case, when the record is being saved the system will check against the database to ensure that the username is unique. As mentioned above, this method supports the :on option. This validator also supports a :scope option that limits the scope of uniqueness, meaning that the combination of the values of the named attribute and those listed in the :scope option must be unique.

The validates_presence_of method insures that the list of attributes are not nil, empty, or blank. In this example the username and password attributes require a non empty string value. This validator also supports the :on option.

The validates_size_of method allows you to define the minimum, or maximum, or exact character size of a attribute. In the example above, I used the within range to indicate both the minimum and maximum size of a string.

The validates_format_of method allows you to validate the value of an attribute against a regular expression. The first example of the validates_format_of above is taken straight from the rails documentation and validates that the email attribute actually looks like an email address. The second validate_format_of method ensures that only alphanumeric characters are used for a username.

The validates_confirmation_of method is used to validate that the password typed in is the one the user intended. To confirm the password entered by a user you need to define two input fields in the form to check that they both match. The system will automatically check that the two password match when the user record is saved. Again, this validator supports the :on option. In my registration page I have a form with the following two password fields.

<label for="user_password">Password</label>
<%= password_field 'user', 'pass' %>
<label for="check_password">Confirm Password</label>
<%= password_field 'user', 'pass_confirmation' %>

The validates_inclusion_of method validates that the value of named attribute is in the list specified by the :in option. In this example, the gender of the user needs to be either male or female. You can also specify a range instead of a list. ActiveRecord also supports a validates_exclusion_of method that validates that the value of a named attribute is not within the range or list provided in the :in option.

The validates_acceptance_of method validates that the user accepted some sort of end user license agreement, term or service, or memorandum of understanding via a checkbox in a from. The validates_acceptance_of validator works only when you define a checkbox in the form. This means that in the registration page you can add the acceptance checkbox so that the user must accept the EULA but you can leave out the acceptance checkbox in the user update page. In this example, only when the form has the eula checkbox does this validator takes effect. For this example here is how you define the acceptance checkbox in your user registration form:

<%= check_box :user, :eula %>

To create the checkbox I am using symbols instead of strings, either one works.

There are a few other rails validators that I did not cover here such as validates_associated which is used to validate ActiveRecord associations, validates_numericality_of which can be used to validate if a form value is a number, and validates_each which allows you to define you own validation code blocks.

Technorati Tags: , , , , , ,


10 Responses to “Rails Model Validators”

Leave a Reply