Validating data with Sequel

Sequel is a pretty nifty database toolkit for Ruby. I have been using it lately in combination with Ramaze - an incredibly fast and powerful web framework (also for Ruby).

Sequel has perfect documentation in terms of an API, and the cheatsheet and readme give a good summary of how to use the features, but there's not too much out there that can gives a gentle introduction.

There will be a few posts published here that try and give such an introduction to various aspects of Sequel.

This one is a quick run down of how you validate database fields in Sequel.

The model to validate

For this example, we will use a simple User model - not very original, I know:

class User < Sequel::Model(:users)
set_schema do
primary_key :id
varchar :username
varchar :email
int :house_number
varchar :zip_code
end
end

Basic validation

Sequel comes with some built in validation rules which will satisfy most people's needs straight off. They are mentioned at the bottom of the readme, and detailed in the RDoc page (scroll down a bit to see everything).

A brief demonstration of some of these validations, in context:

validations.clear
validates do
presence_of :username, :email, :house_number
uniqueness_of :email
numbericality_of :house_number
length_of :username, :minimum => 6, :maximum => 10
format_of :zip_code, :with => '/(^\d{5}$)|(^\d{5}-\d{4}$)/'
end

Pretty self explanatory stuff when you see it in action.

The presence_of makes sure all fields specified have been given a value, uniqueness_of makes sure that there is only one instance of that value in the table (useful when registering users by e-mail address, for example).

The format_of allows you to validate a specified field against a regular expression. I'm not actually sure if that ZIP code regex works, don't quote me!

These will be run when you try and save a new model or update an existing one - if the model fails to save, the instance of the model will be returned with the errors property set - you can inspect this to see what the problem is.

Advanced validation

As mentioned, the basic validation should be sufficient for most people, but not everyone. I have found myself needing to validate fields with a higher degree of control. For example, you might want to use some obscure criteria, or need to perform some action on the field to see if it is valid or not.

To demonstrate this, we will only allow odd house numbers to be saved:

validates_each :house_number do |object, attribute, value|
object.errors[attribute] << 'No even house numbers allowed!' unless value % 2 == 1
end

You would put this underneath the previous code block.

You could call a method that returns true or false based on whatever critera you choose:

#...
unless checkMyValue value