The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
What's New in Edge Rails: Independent Model Validators

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
rwdaigle

Posts: 312
Nickname: rwdaigle
Registered: Feb, 2003

Ryan is a passionate ruby developer with a strong Java background.
What's New in Edge Rails: Independent Model Validators Posted: Aug 11, 2009 12:48 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by rwdaigle.
Original Post: What's New in Edge Rails: Independent Model Validators
Feed Title: Ryan's Scraps
Feed URL: http://feeds.feedburner.com/RyansScraps
Feed Description: Ryan Daigle's various technically inclined rants along w/ the "What's new in Edge Rails" series.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by rwdaigle
Latest Posts From Ryan's Scraps

Advertisement

This feature is schedule for: Rails v3.0

ActiveRecord validations, ground zero for anybody learning about Rails, got a lil’ bit of decoupling mojo today with the introduction of validator classes. Until today, the only options you had to define a custom validation was by overriding the validate method or by using validates_each, both of which pollute your models with gobs of validation logic.

ActiveRecord Validators

Validators remedy this by containing granular levels of validation logic that can be reused across your models. For instance, for that classic email validation example we can create a single validator:

1
2
3
4
5
6
class EmailValidator < ActiveRecord::Validator
  def validate()
    record.errors[:email] << "is not valid" unless
      record.email =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  end
end

Each validator should implement a validate method, within which it has access to the model instance in question as record. Validation errors can then be added to the base model by adding to the errors collection as in this example.

So how do you tell a validator to operate on a model? validates_with that takes the class of the validator:

1
2
3
class User < ActiveRecord::Base
  validates_with EmailValidator
end

Validation Arguments

This is all well and good, but is a pretty brittle solution in this example as the validator is assuming an email field. We need a way to pass in the name of the field to validate against for a model class that is unknown until runtime. We can do this by passing in options to validates_with which are then made available to the validator at runtime as the options hash. So let’s update our email validator to operate on an email field that can be set by the model requiring validation:

1
2
3
4
5
6
7
class EmailValidator < ActiveRecord::Validator
  def validate()
    email_field = options[:attr]
    record.errors[email_field] << "is not valid" unless
      record.send(email_field) =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  end
end

And to wire it up from the user model:

1
2
3
class User < ActiveRecord::Base
  validates_with EmailValidator, :attr => :email_address
end

Any arguments can be passed into your validators by hitching a ride onto this options hash of validates_with.

Options & Notes

There are also some built-in options that you’ll be very familiar with, namely :on, :if and :unless that define when the validation will occur. They’re all the same as the options to built-in validations like validates_presence_of.

1
2
3
4
class User < ActiveRecord::Base
  validates_with EmailValidator, :if => Proc.new  { |u| u.signup_step > 2 },
    :attr => :email_address
end

It’s also possible to specify more than one validator with validates_with:

1
2
3
class User < ActiveRecord::Base
  validates_with EmailValidator, ZipCodeValidator, :on => :create
end

While this might seem like a pretty minor update, it allows for far better reusability of custom validation logic than what’s available now. So enjoy.

tags: ruby, rubyonrails

Read: What's New in Edge Rails: Independent Model Validators

Topic: Agilepalooza in Charlotte Previous Topic   Next Topic Topic: My Apprenticeship - Monday, August 9, 2004

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use