Saturday, February 9, 2008

Custom Rails Validations - Keeping it DRY(2)

Last week I added a custom validation for zip/postal codes. Now we make that available to all ActiveRecord models.

The best way is to create a plugin for all your custom validations. We have a plugin for all our ActiveRecord extensions. Its easier to test and its reusable across projects.

So we have our Validations module location in 'vendor/plugins/active_record_ext/lib'

module ValidationSystem
def self.included(base) # :nodoc:
base.extend ClassMethods
end

module ClassMethods
def validates_as_zip_code(*attr_names)
configuration = {
:message => 'is an invalid zip code',
:with => /(^\d{5}$)|(^\d{5}-\d{4}$)|(^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d)/,
:allow_nil => false}
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
validates_format_of attr_names, configuration
end
end

end


Now we just need to tell ActiveRecord to include this in Base so its available for all model classes.

'vendor/plugins/active_record_ext/init.rb'

ActiveRecord::Base.class_eval do
include ValidationSystem
end

No comments: