Reputation: 283
How do you validate a U.S. zip code using Rails?
I wrote something like this but it doesn't work:
validates_format_of :zip_code,
:with => /^\d{5}(-\d{4})?$/,
:message => "Zip code should be valid"
Upvotes: 14
Views: 20567
Reputation: 151
This worked for me: (ruby-2.0.0-p247, rails 4.0.0)
validates_format_of :zip_code,
with: /\A\d{5}-\d{4}|\A\d{5}\z/,
message: "should be 12345 or 12345-1234",
allow_blank: true
Upvotes: 12
Reputation: 10796
If you need multi-country support, you can use validates_zipcode
gem I released. It currently supports 159 countries zipcode formats and plays nice with Rails 3 & 4.
You can use it like this:
class Address < ActiveRecord::Base
validates_zipcode :zipcode
validates :zipcode, zipcode: true
validates :zipcode, zipcode: { country_code: :ru }
validates :zipcode, zipcode: { country_code_attribute: :my_zipcode }
end
Upvotes: 4
Reputation: 33732
those are both good answers!
another idea is to create you own custom validation , which not only checks that the number of digits is correct, but also checks with a database in the background, that the zip-codes exist..
e.g. these Gems could help:
geokit , check here: Best Zip Code Plugin for Ruby
zip-code-info , http://rubygems.org/gems/zip-code-info
http://zipcodesearch.rubyforge.org/
Upvotes: 0
Reputation: 96504
You can also validate that it is actually a valid zip (not just the format but the zip itself) using:
http://www.webservicex.net/uszip.asmx?op=GetInfoByZIP
Try a valid zip you know, e.g. 02135 vs an invalid one like 09990 to see the difference.
I would consider combining this with:
validates_format_of :zip, :with => /^\d{5}(-\d{4})?$/, :message => "should be in the form 12345 or 12345-1234"
that it's done with validate_format_of
, rather than validate_format_of_zip_code
as that means it can also be used for phone numbers, etc that also fit a fixed, known, format (.e.g. U.S.).
Perhaps validate format first and give error if invalid, so handle it all within rails with standard flash message.
Then, if valid make the call to that server to validate actual zip itself.
The only downside to great server supplied validations like this is that they increase the dependency on other sites and services. So if the other site/service changes things or is unavailable, etc. there is an issue. This is another reason why doing the simpler validity check first is a great idea.
A full service solution would also check for time-out by the zip code service and if that happens, say 5 seconds and the format is ok probably best to accept value. Maybe set an 'unverified_zip' flag if possible!
Upvotes: 20
Reputation: 34224
ZIP codes in the US are either 5 digits or 5 digits plus 4 digits for the area code. Try the following:
validates_format_of :zip_code,
:with => %r{\d{5}(-\d{4})?},
:message => "should be 12345 or 12345-1234"
Upvotes: 0