Last active
November 16, 2023 15:13
-
-
Save harlow/5368275 to your computer and use it in GitHub Desktop.
Extract a validator in Rails. Zip code validation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/user.rb | |
class User < ActiveRecord::Base | |
validates :zip_code, presence: true, zip_code: true | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/validators/zip_code_validator.rb | |
class ZipCodeValidator < ActiveModel::EachValidator | |
ZIP_CODE_REGEX = /^\d{5}(-\d{4})?$/ | |
def validate_each(record, attribute, value) | |
unless ZIP_CODE_REGEX.match value | |
record.errors.add(attribute, "#{value} is not a valid zip code") | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# spec/validators/zip_code_validator_spec.rb | |
require 'spec_helper' | |
describe ZipCodeValidator, '#validate_each' do | |
it 'does not add errors with a valid zip code' do | |
record = build_record('93108') | |
ZipCodeValidator.new(attributes: :zip_code).validate(record) | |
record.errors.should be_empty | |
end | |
it 'adds errors with an invalid zip code' do | |
record = build_record('invalid_zip') | |
ZipCodeValidator.new(attributes: :zip_code).validate(record) | |
record.errors.full_messages.should eq [ | |
'Zip code invalid_zip is not a valid zip code' | |
] | |
end | |
def build_record(zip_code) | |
test_class.new.tap do |object| | |
object.zip_code = zip_code | |
end | |
end | |
def test_class | |
Class.new do | |
include ActiveModel::Validations | |
attr_accessor :zip_code | |
def self.name | |
'TestClass' | |
end | |
end | |
end | |
end |
You should use \A
and \z
as anchors in your regex. http://stackoverflow.com/a/3632051
Hey!
I ended up pulling some bits together into this gem: validates_zipcode
.
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
Cheers!
@dgilperez @harlow - This validator doesn't seem to work if you're using "presence: false". I might recommend using "unless PHONE_REGEX.match(value) || value.blank?" so that a developer can use the presence attribute.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi!
Thanks for sharing :)
I'm generalizing the Validator to support different countries. Check it out if you want: https://gist.github.com/dgilperez/6232901
Cheers!