Skip to content

Instantly share code, notes, and snippets.

@knzconnor
Forked from bluemont/url_validator.rb
Last active December 14, 2015 16:09
Show Gist options
  • Save knzconnor/5113293 to your computer and use it in GitHub Desktop.
Save knzconnor/5113293 to your computer and use it in GitHub Desktop.
Totally untested, just forked and tweaked for discussion
require 'addressable/uri'
#Accepts options[:message] and options[:allowed_protocols]
class UriValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
uri = parse_uri(value)
if !uri
record.errors[attribute] << generic_failure_message
elsif !allowed_protocols.include?(uri.scheme)
record.errors[attribute] << "must begin with #{allowed_protocols_humanized}"
end
end
private
def generic_failure_message
options[:message] || "is an invalid URL"
end
def allowed_protocols_humanized
allowed_protocols.to_sentence(:two_words_connector => 'or')
end
def allowed_protocols
@allowed_protocols ||= ([options[:allowed_protocols]].flatten || ['http', 'https'])
end
def parse_uri
Addressable::URI.parse(value)
rescue URI::InvalidURIError
end
end
describe UriValidator do
subject do
Class.new do
include ActiveModel::Validations
validates_with UriValidator
attr_accessor :url
end.new
end
it "should be valid for a valid http url" do
subject.url = 'http://www.google.com'
subject.should be_valid
end
end
@gmile
Copy link

gmile commented Jun 17, 2013

Line 29 of uri_validator.rb should be:

def parse_uri(value)

@mwarren
Copy link

mwarren commented Jul 4, 2013

UriValidator#allowed_protocols should be:

def allowed_protocols
  @allowed_protocols ||= [(options[:allowed_protocols] || ['http', 'https'])].flatten
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment