Michał Makaruk
Michał Makaruk

Reputation: 283

Validate US Zip Code format with Rails

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

Answers (5)

Ariel
Ariel

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

dgilperez
dgilperez

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

Tilo
Tilo

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

Michael Durrant
Michael Durrant

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

halfdan
halfdan

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

Related Questions