Last Updated: February 25, 2016
·
27.59K
· leemachin

Validate URLs in Rails

Take this code:

class UrlValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors[attribute] << (options[:message] || "must be a valid URL") unless url_valid?(value)    
  end

  # a URL may be technically well-formed but may 
  # not actually be valid, so this checks for both.
  def url_valid?(url)
    url = URI.parse(url) rescue false
    url.kind_of?(URI::HTTP) || url.kind_of?(URI::HTTPS)
  end 
end

Save it in your app directory so it's autoloaded, eg:

app/validators/url_validator.rb

And use it in your model thus:

class Something < ActiveRecord::Base
    validates :link, url: true
end

Credit to StackOverflow for pointing me in the right direction.

Source + Tests

6 Responses
Add your response

thanks!

over 1 year ago ·

Great little validator. Thanks for your effort.
One thing's missing though, i18n.

over 1 year ago ·

Nice. But the problem is that it allows http:google.com, http:/google.com, http:///google.com and such...

over 1 year ago ·
over 1 year ago ·

url.kind_of?(URI::HTTP)
should be sufficient for both 'http' and 'https' case.

over 1 year ago ·

Just an idea:

require 'uri'

class UrlValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value =~ /^#{URI::regexp}$/
      record.errors[attribute] << (options[:message] || "is not an url")
    end
  end
end
over 1 year ago ·