Walidacja URL

Jak robicie walidację URL?

Chcę, żeby się łapały takie:

urls = %w(http://www.foo.pl https://foo.com foo.com bar.com/pl?test=2&x=1)

A nie łapały te:

urls = %w(.foo.pl tps://foo.com foo http://foo.)

Mój model wygląda tak:

class Link < ActiveRecord::Base
  validates :url, presence: true
  validates :url, format: URI::regexp(%w(http https))

  before_validation do
    if url.present? && (/^(http:\/\/|https:\/\/)/ =~ url.downcase).nil?
      self.url = "http://#{url}"
    end
  end
end

Niestety, nie za bardzo działa, bo pod tego regexpa łapie się praktycznie wszystko co ma protokół z przodu.

Może https://github.com/ralovets/valid_url ?

Próbowałem, ale też za dużo łapie :confused:

Przyznam bez bicia, że przejżałem tylko testy tego gema i wyglądały sensownie.

A czemu nie chcesz, żeby Ci się nie łapało http://foo. ?

URL-e z kropką po nazwie domeny są legalne: http://www.dns-sd.org/trailingdotsindomainnames.html

W sumie nie ma większego powodu, chciałem po prostu, żeby ludzie wrzucali ‘standardowe’ linki, ale może, rzeczywiście, za bardzo sobie to komplikuje.

Też się kiedyś dużo z tym męczyłem, aż w końcu stwierdziłem, że lepiej to zrobić po stronie front-endu.

A czemu nie użyć URI.parse; złapać wyjątki, jakie polecą gdy url jest niepoprawny i sprawdzić czy url.scheme to http lub https?

http://ruby-doc.org/stdlib-2.2.0/libdoc/uri/rdoc/URI.html#method-c-parse