Mam pewien problem, kilka linijek kodu, ogólnie działa, ale w moim validatorze nie.
Mam model Entry z polem :url
Chcę sprawdzić czy to pole ma dobry format. Na stack-overflow znalazlem coś takiego(nie 100%, ale zasada ta sama):
require 'uri'
begin
URI.parse("http://onet!!t.pl")
rescue URI::InvalidURIError
puts "FALSE"
end
I to fajnie działa, pokazuje mi FALSE, jak jest zły adres.
Teraz w moim modelu daję validację:
validates :url, uri_format: true
W katalogu apps/validators utworzyłem plik uri_format_validator.rb:
class UriFormatValidator < ActiveModel::EachValidator
def validate_each(record,attribute,value)
URI.parse(value)
rescue URI::InvalidURIError
record.errors[attribute] << "is not an URL format"
end
end
Nawet jak już chamsko zamiast (value) wstawiam (“one!!t.pl”) to nie działa.
Będę wdzięczny za podpowiedź, co robię nie tak, bo siedzę nad tymi kilkoma linijkami już kilka godzin
Chyba wyrzica, bo dostaję taki błąd przy samym wywyołaniu:
initialize': the scheme http does not accept registry part: onet!!t.pl (or bad hostname?) (URI::InvalidURIError)
ps. dzieki zlw za linka, działa
Będę wdzięczny za podpowiedź, dlaczego mój kod:
class UriFormatValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
begin #tutaj próbowałem i z begin i bez
URI.parse(value)
rescue URI::InvalidURIError
record.errors[attribute] << (options[:message] || "is an invalid URL")
end
end
end
Tłumaczyłem sobie to tak, że próbuję odpalić URI.parse(value) , co przetestowałem na prostym skrypciku i jak rzuca mi tym wyjątkiem to ustawiam record.error:
require 'uri'
begin
URI.parse("http://onet!!t.pl")
puts "TRUE"
rescue URI::InvalidURIError
puts "FALSE"
end
To nie mam pojęcia czemu u ciebie jest tak, u mnie jeszcze raz w konsoli sprawdziłem:
1.9.3-p194 :002 > require 'uri'
=> true
1.9.3-p194 :003 > URI.parse("http://onet!!t.pl")
URI::InvalidURIError: the scheme http does not accept registry part: onet!!t.pl (or bad hostname?)
Edit, a ok, już widzę to przez to, że ja wrzucam z http.
Zakończyło się tak, że jednak wykorzystałem jakiegoś zwykłego regexpa (http://www.railsmine.net/2010/09/ruby-way-to-do-url-validation.html), bo ten URI.parse puszcza jako ok praktycznie wszystko co ma dobrze ustawiony protokół “http://” czyli onet…pl czy -onet.pl (mozliwe ze jak nazwa wskazuje, to jest raczej do parsowania poprawnych url, a nie do ich validowania)
class UriFormatValidator < ActiveModel::EachValidator
VALID_URL_REGEXP = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix
def validate_each(record, attribute, value)
url="http://"+value.sub(/^(http:\/\/|https:\/\/)/,"")
record.errors[attribute] << (options[:message] || "is an invalid URL") unless url=~VALID_URL_REGEXP
end
end