Skip to content

Instantly share code, notes, and snippets.

@tochman
Forked from knzai/uri_validator.rb
Last active August 29, 2015 13:57
Show Gist options
  • Select an option

  • Save tochman/9366913 to your computer and use it in GitHub Desktop.

Select an option

Save tochman/9366913 to your computer and use it in GitHub Desktop.
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 ||= Array((options[:allowed_protocols] || ['http', 'https']))
end
def parse_uri(value)
uri = Addressable::URI.parse(value)
uri.scheme && uri.host && uri
rescue URI::InvalidURIError, Addressable::URI::InvalidURIError, TypeError
end
end
require 'spec_helper'
# from https://gist.github.com/timocratic/5113293
describe UriValidator do
subject do
Test = Class.new do
include ActiveModel::Validations
attr_accessor :url
validates :url, uri: true
end
Test.new
end
it "should be valid for a valid http url" do
subject.url = 'http://www.google.com'
subject.valid?
subject.errors.full_messages.should == []
end
['http:/www.google.com','<>hi'].each do |invalid_url|
it "#{invalid_url.inspect} is an invalid url" do
subject.url = invalid_url
subject.valid?
subject.errors.should have_key(:url)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment