This post originated from an RSS feed registered with Ruby Buzz
by Jay Fields.
Original Post: Ruby: Validatable 1.2.2 released
Feed Title: Jay Fields Thoughts
Feed URL: http://blog.jayfields.com/rss.xml
Feed Description: Thoughts on Software Development
The Validatable gem received a fair amount of attention in the past few weeks. Thanks to Ali Aghareza, Jason Miller, Xavier Shay, and Anonymous Z for their contributions.
Validation Groups On my previous project we found that our object.valid? method needed to depend on the role that an object was currently playing. This led to the introduction of groups.
Validation groups can be used to validate an object when it can be valid in various states. For example a mortgage application may be valid for saving (saving a partial application), but that same mortgage application would not be valid for underwriting. In our example a application can be saved as long as a Social Security Number is present; however, an application can not be underwritten unless the name attribute contains a value.
class MortgageApplication include Validatable validates_presence_of :ssn, :groups => [:saving, :underwriting] validates_presence_of :name, :groups => :underwriting attr_accessor :name, :ssn end
As you can see, you can use an array if the validation needs to be part of various groups. However, if the validation only applies to one group you can simply use a symbol for the group name.
The inspiration for adding this functionality came from the ContextualValidation entry by Martin Fowler.
validates_true_for The validates_true_for method was added to allow for custom validations.
The validates_true_for method can be used to specify a proc, and add an error unless the evaluation of that proc returns true.
class Person include Validatable validates_true_for :first_name, :logic => lambda { first_name == 'Book' } attr_accessor :first_name end
validates_numericality_of This release also adds the validates_numericality_of method. The validates_numericality_of method takes all of the standard parameters that the other validations take: message, times, level, if, group.
Validates that the specified attribute is numeric.
class Person include Validatable validates_numericality_of :age end
after_validate hook method Another new feature of this release is the after_validate hook. This feature allows you to manipulate the instance after a validation has been run. For example, perhaps you are happy with the default messages; however, you also want the attribute to be appended to the message. The following code uses that example and shows how the after_validate hook can be used to achieve the desired behavior.
class Person include Validatable validates_presence_of :name attr_accessor :name end
class ValidatesPresenceOf after_validate do |result, instance, attribute| instance.errors.add("#{attribute} can't be blank") unless result end end
person = Person.new person.valid? #=> false person.errors.on(:name) #=> "name can't be blank"
The after_validate hook yields the result of the validation being run, the instance the validation was run on, and the attribute that was validated.
include_validations_for takes options The include_validations_for method was changed to accept options. The currently supported options for include_validations_for are :map and :if.
class Person include Validatable validates_presence_of :name attr_accessor :name end
class PersonPresenter include Validatable include_validations_for :person, :map => { :name => :namen }, :if => lambda { not person.nil? } attr_accessor :person
The person attribute will be validated. If person is invalid the errors will be added to the PersonPresenter errors collection. The :map option is used to map errors on attributes of person to attributes of PersonPresenter. Also, the :if option ensures that the person attribute will only be validated if it is not nil.
validates_confirmation_of The validates_confirmation_of method now takes the :case_sensitive option. If :case_sensitive is set to false, the confirmation will validate the strings based a case insensitive comparison.
validates_length_of The validates_length_of method now takes the :is option. If the :is option is specified, the length will be required to be equal to the value given to :is.
Bugs The comparison in validates_format_of was changed to call to_s on the object before execution. The new version allows you to validate the format of any object that implements to_s.