验证模型中的URL属性

时间:2014-05-15 11:40:55

标签: ruby-on-rails ruby regex

我有一个模型引用了一个带有缩略图列的表。至于验证,我希望缩略图接受空/零或有效网址(理想情况下为jpg / gif)的值。以下是我的尝试,但它似乎没有按预期验证。有人可以看下面我的模型并告诉我哪里出错了,谢谢

class SearchResult < ActiveRecord::Base

  validate :check_thumbnail

  private
    def check_thumbnail
      if self.thumbnail.nil?
        true
      else
        if /https?:\/\/[\S]+/.match(self.thumbnail).nil?
          false
        else
          false
        end
      end
    end
end

3 个答案:

答案 0 :(得分:2)

使用official guide进行自定义验证我建议您在url_validator.rb中使用以下内容创建app/validators

class UrlValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors[attribute] << (options[:message] || 'must be a valid URL') unless url_valid?(value)
  end

  def url_valid?(url)
    uri = URI.parse(url) rescue false
    uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
  end
end

此后您可以验证thumbnail这样的属性:

class SearchResult < ActiveRecord::Base
  validates :thumbnail, url: true, allow_blank: true
end

此外,您可以通过正则表达式改进url_valid?方法以考虑扩展白名单(但我会为此创建另一个验证程序,例如image_url_validator.rb以保留基本网址验证程序。)

修改

应用程序/验证器/ image_url_validator.rb

class ImageUrlValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors[attribute] << (options[:message] || 'must be a valid URL (only jpg and gif)') unless url_valid?(value)
  end

  def url_valid?(url)
    uri = URI.parse(url) rescue false
    (uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)) && uri.to_s.match(/\.jpg|\.gif/)
  end
end

应用程序/模型/ search_result.rb

class SearchResult < ActiveRecord::Base
  validates :thumbnail, image_url: true, allow_blank: true
end 

此方法的主要优点是您可以将此自定义验证重用于不同模型中的不同属性。

答案 1 :(得分:1)

我会把它重写为

class SearchResult < ActiveRecord::Base

validate :check_thumbnail

private
  def check_thumbnail
    unless self.thumbnail.blank? || self.thumbnail =~ /https?:\/\/[\S]+/
      self.errors.add(:thumbnail, "is not valid")
    end
  end
end

答案 2 :(得分:-1)

使用此正则表达式验证网址,我自己使用了

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

这里是你在else块中的代码,这样做

  else
    URL_REGEX = /\A(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?\z/ix
    if (URL_REGEX).match(self.thumbnail).nil?
      false
    else
      false
    end
  end