validates_format_of
- 1.0.0
- 1.1.6
- 1.2.6
- 2.0.3
- 2.1.0 (0)
- 2.2.1 (0)
- 2.3.8 (0)
- 3.0.0
- 3.0.9
- 3.1.0
- 3.2.1
- 3.2.8
- 3.2.13
- 4.0.2
- 4.1.8
- 4.2.1
- 4.2.7
- 4.2.9
- 5.0.0.1
- 5.1.7
- 5.2.3
- 6.0.0
- 6.1.3.1
- 6.1.7.7
- 7.0.0
- 7.1.3.2
- 7.1.3.4
- What's this?
validates_format_of(*attr_names)
public
Validates whether the value of the specified attribute is of the correct form by matching it against the regular expression provided.
class Person < ActiveRecord::Base validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create end
Note: use \A and \Z to match the start and end of the string, ^ and $ match the start/end of a line.
A regular expression must be provided or else an exception will be raised.
Configuration options:
- :message - A custom error message (default is: "is invalid")
- :allow_nil - If set to true, skips this validation if the attribute is nil (default is: false)
- :allow_blank - If set to true, skips this validation if the attribute is blank (default is: false)
- :with - The regular expression used to validate the format with (note: must be supplied!)
- :on - Specifies when this validation is active (default is :save, other options :create, :update)
- :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.
Using validates_format_of to validate URIs
You can use the validates_format_of with the regular expression in the URI library ensure valid URIs.
Example
require 'uri' class Feed < ActiveRecord::Base validates_format_of :uri, :with => URI.regexp end
RE: Using validates_format_of to validate URIs
Further to Olly’s note below, you can also specify the protocol to further limit the valid uri’s, else things like ‘ftp ://someurl.com’ (there’s only a space in there to get it to display on here) would be valid.
validates_format_of :uri, :with => URI.regexp(['http'])
Take care when writing regex
When you want to validate a field for a continuous string you’d probably write something like this (if it’s really early in the morning and you didn’t have your coffee yet):
validates_format_of :something => /\w/
At the first sight it looks like it’s working because something = “blahblahblah” is valid. However, so is this: something = “blah meh 55”. It’s just that your regex matched a substring of the value and not the whole thing. The proper regex you’re looking for is actually:
validates_format_of :something => /^\w$/
Re: Taking care when writing regex
Oleg’s example from above contains an error and a pitfall:
validates_format_of :something => /^\w$/
The string “blahblahblah” doesn’t pass this validation. What Oleg ment is rather a continuous string of at least one alphanumeric character:
validates_format_of :something => /^\w+$/
However, that’s no good neither because it contains a well hidden trap in case you are validating content from a textarea.
Ruby (both 1.8 and 1.9) always matches ^ and $ against the beginning and ending of lines and not the entire string. Thus “First linenSecond line” will pass the above validation although it’s clearly not a continuous string.
You should use A (replacement for ^) and z (replacement for $) instead as their scope is the entire string:
validates_format_of :something => /\A\w+\z/
(A side note for those with a Perl background: Please note that the “s” modifier has a different meaning in Ruby and won’t do the trick here.)
No numbers or symbols
“Kyle”, “Дети”, “Niños”, “Quan-lu”, “た ち”
validates_format_of :first_name, :with => /^([^\d\W]|[-])*$/
note: the example format regex is too lenient
The example regex for RFC 2822 email is too lenient. Sure it’s just an example, but it wound up in our code and we just had to fix it to match the RFC.
The regex as given allows any non-@ non-whitespace characters. But the RFC only allows these characters in mailbox names
alpha digit - ! \ # $ % & ' * + \ / = ? ^ _ ` { | } ~ ] +
and . is only allowed between atoms of 1 or more of the above.
Here’s the corrected regex:
:with => /\A([-a-z0-9!\#$%&'*+\/=?^_`{|}~]+\.)*[-a-z0-9!\#$%&'*+\/=?^_`{|}~]+@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
Example Regex format matching
for phone and email
validates_format_of :phone, with: /\A(\d{10}|\(?\d{3}\)?[-. ]\d{3}[-.]\d{4})\z/ validates_format_of :email, with: /\A[\w]([^@\s,;]+)@(([\w-]+\.)+(com|edu|org|net|gov|mil|biz|info))\z/i