Created
June 4, 2012 05:56
-
-
Save bradhe/2866579 to your computer and use it in GitHub Desktop.
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
require 'uri/http' | |
# Blatently stolen from http://www.simonecarletti.com/blog/2009/04/validating-the-format-of-an-url-with-rails/ | |
# | |
# Validates whether the value of the specified attribute matches the format of an URL, | |
# as defined by RFC 2396. See URI#parse for more information on URI decompositon and parsing. | |
# | |
# This method doesn't validate the existence of the domain, nor it validates the domain itself. | |
# | |
# Allowed values include http://foo.bar, http://www.foo.bar and even http://foo. | |
# Please note that http://foo is a valid URL, as well http://localhost. | |
# It's up to you to extend the validation with additional constraints. | |
# | |
# class Site < ActiveRecord::Base | |
# validates_format_of :url, :on => :create | |
# validates_format_of :ftp, :schemes => [:ftp, :http, :https] | |
# end | |
# | |
# ==== Configurations | |
# | |
# * :schemes - An array of allowed schemes to match against (default is [:http, :https]) | |
# * :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+). | |
# * :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. | |
# | |
# | |
class UrlValidator < ActiveModel::EachValidator | |
def validate_each(record, attribute, value, options = {}) | |
default_options = { | |
schemes: [:http, :https] | |
} | |
settings = default_options.merge(options.symbolize_keys) | |
uri = URI.parse(value) | |
unless settings[:schemes].include?(uri.scheme.try(:to_sym)) | |
add_error_message(record, attribute, value, settings) | |
end | |
if [:scheme, :host].any? { |i| uri.send(i).blank? } | |
add_error_message(record, attribute, value, settings) | |
end | |
rescue URI::InvalidURIError => e | |
add_error_message(record, attribute, value, settings) | |
end | |
def add_error_message(record, attr_name, value, settings) | |
record.errors.add(attr_name, :invalid, :default => settings[:message], :value => value) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment