使用 Carrierwave,在尝试将其保存到记录之前如何确保远程 url 是有效图片?

Using Carrierwave, how can I make sure the remote url is valid picture before trying to save it to the record?

我试图在我的 ActiveJob 中以下列方式保存我的图片文件,但我的很多记录都显示为无效。调查原因后,遥控器 url 似乎没有找到有效图片,并返回 404 错误消息。我怎样才能将我当前的设置更改为 (1) 尝试获取图片,(2) 如果它无效 link 然后忽略它并仍然保存记录 - 只是没有图片?

我当前的设置...

if self.headshot_url.present?
   player_record.remote_headshot_image_url = self.headshot_url
   if !player_record.valid?
     player_record.remote_headshot_image_url = nil
   end
end

您可能想要HEAD http-request 图片url,并检查响应headers。

我经常使用 FastImage gem 来快速查找图像大小和类型。您也可以使用它来检查图像是否有效。

FastImage.type('https://github.com/sdsykes/fastimage') 
=> nil

FastImage.type('https://www.google.ru/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png')
 => :png 

Ruby 有一个 stdlib HTTP library 可以使用:

uri = URI('http://example.com/some_path?query=string')

Net::HTTP.start(uri.host, uri.port) do |http|
  response = http.head('/')
  if response.is_a?(Net::HTTPSuccess)
    puts "Yay"
  else
    puts "Oh noes"
  end
end

要创建检查 URL 是否有效的验证,您可以这样做:

require 'net/http'
class Thing < ApplicationRecord
  validates :headshot_url_must_be_valid, if: -> { headshot_url.present? }

  def headshot_url_must_be_valid
    uri = URI(headshot_url)
    Net::HTTP.start(uri.host, uri.port) do |http|
     response = http.head('/')
     unless response.is_a?(Net::HTTPSuccess)
       # This is how you would normally do validation
       # errors.add(:headshot_url, "is invalid. #{res.code} - #{res.msg}")
       self[:headshot_url] = nil
     end
    end
  end
end