class UrlValidator

Checks if the value of an attribute is a valid URL.

@example Validate that the user’s blog URL is valid.

class User << ActiveRecord::Base
  attr_accessor :blog, :name
  validates :blog, url: true
end

Public Instance Methods

validate_each(record, attribute, value) click to toggle source

Checks if an attribute value is a valid URL.

@param [Object] record object to validate @param [String] attribute name of the object attribute to validate @param [Object] value attribute value

# File lib/missing_validators/validators/url_validator.rb, line 15
def validate_each(record, attribute, value)
  uri = parse(value)
  fail Addressable::URI::InvalidURIError unless valid?(uri, options)
rescue
  record.errors[attribute] << options.fetch(:message) do
    I18n.t('errors.messages.url')
  end
end

Private Instance Methods

parse(url) click to toggle source
# File lib/missing_validators/validators/url_validator.rb, line 26
def parse(url)
  Addressable::URI.parse(url).tap do |uri|
    fail Addressable::URI::InvalidURIError if uri.nil? || uri.host.nil?
  end
end
valid?(uri, options) click to toggle source
# File lib/missing_validators/validators/url_validator.rb, line 58
def valid?(uri, options)
  validate_host(uri) && \
    validate_top_level_domain(uri, *options[:domain]) && \
    validate_scheme(uri, *options[:scheme]) && \
    (options[:root] == true ? validate_root(uri) : true)
end
validate_host(uri) click to toggle source
# File lib/missing_validators/validators/url_validator.rb, line 32
def validate_host(uri)
  !uri.host.include?(' ') && \
    uri.host.include?('.') && \
    uri.host.split('.').last.length > 1
end
validate_root(uri) click to toggle source
# File lib/missing_validators/validators/url_validator.rb, line 52
def validate_root(uri)
  ['/', ''].include?(uri.path) && \
    uri.query.blank? && \
    uri.fragment.blank?
end
validate_scheme(uri, *schemes) click to toggle source
# File lib/missing_validators/validators/url_validator.rb, line 45
def validate_scheme(uri, *schemes)
  return true if schemes.empty?

  scheme_downcased = uri.scheme.to_s.downcase
  schemes.any? { |scheme| scheme_downcased == scheme.to_s.downcase }
end
validate_top_level_domain(uri, *domains) click to toggle source
# File lib/missing_validators/validators/url_validator.rb, line 38
def validate_top_level_domain(uri, *domains)
  return true if domains.empty?

  host = uri.host.to_s.downcase
  domains.any? { |domain| host.end_with?(".#{domain.downcase}") }
end