Rails: Какой хороший способ проверки ссылок (URL)? - PullRequest
118 голосов
/ 24 августа 2011

Мне было интересно, как мне лучше всего проверить URL в Rails. Я думал об использовании регулярного выражения, но не уверен, что это лучшая практика.

И, если бы я использовал регулярное выражение, мог бы кто-нибудь мне его предложить? Я все еще новичок в Regex.

Ответы [ 20 ]

3 голосов
/ 15 февраля 2014

Я использую небольшое отклонение от решения Лафебера выше Он запрещает последовательные точки в имени хоста (например, в www.many...dots.com):

%r"\A(https?://)?[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]{2,6}(/.*)?\Z"i

URI.parse, кажется, требует префикса схемы, что в некоторых случаях не то, что вы можете захотеть (например, если выхотите, чтобы ваши пользователи быстро записывали URL-адреса в таких формах, как twitter.com/username)

2 голосов
/ 07 ноября 2015

Я использовал гем 'activevalidators' , и он работает довольно хорошо (не только для проверки URL)

вы можете найти его здесь

Все это задокументировано, но в основном после добавления гема вы захотите добавить следующие несколько строк в инициализаторе: /config/environments/initializers/active_validators_activation.rb

# Activate all the validators
ActiveValidators.activate(:all)

(Примечание: выможет заменить: все на: url или: что угодно, если вы просто хотите проверить определенные типы значений)

А затем вернуться в вашу модель примерно так:

class Url < ActiveRecord::Base
   validates :url, :presence => true, :url => true
end

Теперь Перезапуститьсервер и это должно быть

1 голос
/ 28 ноября 2014

Недавно у меня возникла такая же проблема, и я нашел способ найти действительные URL.

validates_format_of :url, :with => URI::regexp(%w(http https))
validate :validate_url
def validate_url

  unless self.url.blank?

    begin

      source = URI.parse(self.url)

      resp = Net::HTTP.get_response(source)

    rescue URI::InvalidURIError

      errors.add(:url,'is Invalid')

    rescue SocketError 

      errors.add(:url,'is Invalid')

    end



  end

Первая часть метода validate_url достаточна для проверки формата URL. Вторая часть будет гарантировать, что URL существует, отправив запрос.

1 голос
/ 28 марта 2013

Вы можете проверить несколько URL, используя что-то вроде:

validates_format_of [:field1, :field2], with: URI.regexp(['http', 'https']), allow_nil: true
1 голос
/ 28 марта 2014

https://github.com/perfectline/validates_url - это красивый и простой драгоценный камень, который сделает для вас почти все

1 голос
/ 18 июля 2018

Если вы хотите простую проверку и пользовательское сообщение об ошибке:

  validates :some_field_expecting_url_value,
            format: {
              with: URI.regexp(%w[http https]),
              message: 'is not a valid URL'
            }
0 голосов
/ 21 августа 2018

Мне понравилось monkeypatch модуль URI, чтобы добавить действительный?метод

внутри config/initializers/uri.rb

module URI
  def self.valid?(url)
    uri = URI.parse(url)
    uri.is_a?(URI::HTTP) && !uri.host.nil?
  rescue URI::InvalidURIError
    false
  end
end
0 голосов
/ 13 января 2017

Проверка URL не может быть выполнена просто с помощью регулярного выражения, так как количество веб-сайтов продолжает расти, а новые схемы именования доменов продолжают появляться.

В моем случае я просто пишу пользовательский валидатор, который проверяет успешный ответ.

class UrlValidator < ActiveModel::Validator
  def validate(record)
    begin
      url = URI.parse(record.path)
      response = Net::HTTP.get(url)
      true if response.is_a?(Net::HTTPSuccess)   
    rescue StandardError => error
      record.errors[:path] << 'Web address is invalid'
      false
    end  
  end
end

Я проверяю атрибут path моей модели с помощью record.path. Я также выдвигаю ошибку к соответствующему имени атрибута, используя record.errors[:path].

Вы можете просто заменить его на любое имя атрибута.

Затем я просто вызываю специальный валидатор в моей модели.

class Url < ApplicationRecord

  # validations
  validates_presence_of :path
  validates_with UrlValidator

end
0 голосов
/ 08 июня 2017

Вы можете использовать для этого регулярное выражение, для меня это хорошо работает:

(^|[\s.:;?\-\]<\(])(ftp|https?:\/\/[-\w;\/?:@&=+$\|\_.!~*\|'()\[\]%#,]+[\w\/#](\(\))?)(?=$|[\s',\|\(\).:;?\-\[\]>\)])
0 голосов
/ 17 декабря 2014

И как модуль

module UrlValidator
  extend ActiveSupport::Concern
  included do
    validates :url, presence: true, uniqueness: true
    validate :url_format
  end

  def url_format
    begin
      errors.add(:url, "Invalid url") unless URI(self.url).is_a?(URI::HTTP)
    rescue URI::InvalidURIError
      errors.add(:url, "Invalid url")
    end
  end
end

А затем просто include UrlValidator в любой модели, для которой вы хотите проверить URL-адреса.Просто в том числе для вариантов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...