validates_each
validates_each(*attrs)
public
Adds a validation method or block to the class. This is useful when overriding the validate instance method becomes too unwieldly and you’re looking for more descriptive declaration of your validations.
This can be done with a symbol pointing to a method:
class Comment < ActiveRecord::Base validate :must_be_friends def must_be_friends errors.add_to_base("Must be friends to leave a comment") unless commenter.friend_of?(commentee) end end
Or with a block which is passed the current record to be validated:
class Comment < ActiveRecord::Base validate do |comment| comment.must_be_friends end def must_be_friends errors.add_to_base("Must be friends to leave a comment") unless commenter.friend_of?(commentee) end end
This usage applies to validate_on_create and +validate_on_update as well+.
Validates each attribute against a block.
class Person < ActiveRecord::Base validates_each :first_name, :last_name do |record, attr, value| record.errors.add attr, 'starts with z.' if value[0] == ?z end end
Options:
- :on - Specifies when this validation is active (default is :save, other options :create, :update)
- :allow_nil - Skip validation if attribute is nil.
- :allow_blank - Skip validation if attribute is blank.
- :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
- :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.
Re: Validate an optional URL field
Actually it’s easier to use validates_format_of for this task. Please refer to the comments under the doc.
Validate Mixup
Looks like the docs from validate got mixed up here. Only the last example is actually relevant to validates_each.
Validate an optional URL field
Let’s say that you have an optional URL field to one of your models and you want to validate the URL. You can accomplish this by using the URI library:
require 'uri' # Put this at the beginning of your model file validates_each :url, :allow_blank => true do |record, field, value| begin valid = (URI.parse(value).scheme =~ /https?/) rescue URI::InvalidURIError valid = false end record.errors.add field, "not a valid url" unless valid end
If you want to add even more testing in there, just go ahead. For now, we just check that the link is to a HTTP resource, but you might have other requirements. This will allow stuff like “http://example” since “example” might be a valid intranet domain. If you want to check for a TLD in there, you can do so with a simple regexp.
For more information about the URI library, check out http://apidock.com/ruby/URI/