views:

319

answers:

2

I checked out both of these previously-asked questions, and they're a help but not a full solution for my case.

Essentially I need to validate a user-submitted URL from a form. I've started by validating that it begins with http://, https://, or ftp:// :

class Link < ActiveRecord::Base
  validates_format_of [:link1, :link2, :link3, 
        :link4, :link5], :with => /^(http|https|ftp):\/\/.*/
end

That works great for what it's doing, but I need to go these two steps further:

  1. Users should be allowed to leave the form fields blank if needed, and
  2. If the URL provided by the user does not already start with http:// (say they enter google.com, for example), it should pass the validation but add the http:// prefix while being processed.

I'm having a hard time determining how to make this work cleanly and efficiently.

+3  A: 

FYI, you don't have to pass an array to validates_format_of. Ruby will do arrays automagically (Rails parses the output of *args).

So, for your question, I'd go for something like this:

class Link < ActiveRecord::Base
  validate :proper_link_format

  private

  def proper_link_format
    [:link1, :link2, :link3, :link4, :link5].each do |attribute|
      case self[attribute]
      when nil, "", /^(http|https|ftp):\/\//
        # Allow nil/blank. If it starts with http/https/ftp, pass it through also.
        break
      else
        # Append http
        self[attribute] = "http://#{self[attribute]}"
      end
    end
  end
end
August Lilleaas
+1  A: 

Just to add to the above, I use the Ruby URI module to parse URLs for validity.

http://www.ruby-doc.org/stdlib/libdoc/uri/rdoc/classes/URI.html

It works really well and it helps me to avoid regexes.

hernan43