ztig5g
Last Updated: February 25, 2016
·
13.85K
· 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

Say Thanks
Respond

6 Responses
Add your response

4420
10511630123021da7b3d039d5b748e98

thanks!

over 1 year ago ·
5449
036b3e68b3678855181c39078fb08465

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

over 1 year ago ·
12123
66d27fc45e4161889352fecaac19e20b

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

over 1 year ago ·
13877
0c576e02da6c2316074dbfb778cf4543
over 1 year ago ·
14370
67bfb06524947ade3a12dbd1a1d5c929

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

over 1 year ago ·
14501
C4ad4a18d4572369e5c1556590c2c23b

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 ·