Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails URL Validation (regex)

I'm trying to use a regular expression to validate the format of a URL in my Rails model. I've tested the regex in Rubular with the URL http://trentscott.com and it matched.

Any idea why it fails validation when I test it in my Rails app (it says "name is invalid").

Code:

  url_regex = /^((http|https):\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+).[a-z]{2,5}(:[0-9]{1,5})?(\/.)?$/ix

  validates :serial, :presence => true
  validates :name, :presence => true,
                   :format    => {  :with => url_regex  }
like image 826
Trent Scott Avatar asked Jun 03 '11 18:06

Trent Scott


2 Answers

You don't need to use a regexp here. Ruby has a much more reliable way to do that:

# Use the URI module distributed with Ruby:

require 'uri'

unless (url =~ URI::regexp).nil?
    # Correct URL
end

(this answer comes from this post:)

like image 115
Thomas Hupkens Avatar answered Sep 17 '22 10:09

Thomas Hupkens


(I like Thomas Hupkens' answer, but for other people viewing, I'll recommend Addressable)

It's not recommended to use regex to validate URLs.

Use Ruby's URI library or a replacement like Addressable, both of which making URL validation trivial. Unlike URI, Addressable can also handle international characters and tlds.

Example Usage:

require 'addressable/uri'

Addressable::URI.parse("кц.рф") # Works

uri = Addressable::URI.parse("http://example.com/path/to/resource/")
uri.scheme
#=> "http"
uri.host
#=> "example.com"
uri.path
#=> "/path/to/resource/"

And you could build a custom validation like:

class Example
  include ActiveModel::Validations

  ##
  # Validates a URL
  #
  # If the URI library can parse the value, and the scheme is valid
  # then we assume the url is valid
  #
  class UrlValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      begin
        uri = Addressable::URI.parse(value)

        if !["http","https","ftp"].include?(uri.scheme)
          raise Addressable::URI::InvalidURIError
        end
      rescue Addressable::URI::InvalidURIError
        record.errors[attribute] << "Invalid URL"
      end
    end
  end

  validates :field, :url => true
end

Code Source

like image 20
danneu Avatar answered Sep 21 '22 10:09

danneu