我该怎么做:使用CarrierWave进行远程位置验证?

Was*_*per 5 ruby validation ruby-on-rails ruby-on-rails-3 carrierwave

我在我的Rails 3示例应用程序上使用CarrierWave.我想验证远程位置上传,因此当用户提交无效的URL空白或不是图像时,我不会收到标准错误异常:

CarrierWave::DownloadError in ImageController#create
trying to download a file which is not served over HTTP
Run Code Online (Sandbox Code Playgroud)

这是我的模特:

class Painting < ActiveRecord::Base
  attr_accessible :gallery_id, :name, :image, :remote_image_url
  belongs_to :gallery
  mount_uploader :image, ImageUploader

  validates :name,        :presence => true,
                          :length =>  { :minimum => 5, :maximum => 100 }
  validates :image,       :presence => true

end
Run Code Online (Sandbox Code Playgroud)

这是我的控制器:

class PaintingsController < ApplicationController
  def new
    @painting = Painting.new(:gallery_id => params[:gallery_id])
  end

  def create
    @painting = Painting.new(params[:painting])
    if @painting.save
      flash[:notice] = "Successfully created painting."
      redirect_to @painting.gallery
    else
      render :action => 'new'
    end
  end

  def edit
    @painting = Painting.find(params[:id])
  end

  def update
    @painting = Painting.find(params[:id])
    if @painting.update_attributes(params[:painting])
      flash[:notice] = "Successfully updated painting."
      redirect_to @painting.gallery
    else
      render :action => 'edit'
    end
  end

  def destroy
    @painting = Painting.find(params[:id])
    @painting.destroy
    flash[:notice] = "Successfully destroyed painting."
    redirect_to @painting.gallery
  end
end
Run Code Online (Sandbox Code Playgroud)

我不太确定如何解决这个问题所以任何见解都会很棒.

小智 8

我遇到了同样的问题.不幸的是,这看起来像是CarrierWave的设计缺陷......它不允许对远程URL进行适当的验证.当属性设置时,CarrierWave将立即尝试下载资源,如果url无效,无法访问或资源没有预期类型,则会抛出异常.在进行任何验证之前,始终会抛出DownloadError或IntegrityErrors.

因此,我找不到使用其他验证器的好方法.我的解决方案最终看起来像这样:

valid = false
begin
  par = params[:image].except(:remote_upload_url)
  @image = Image.new(par)
  # this may fail:
  @image.remote_upload_url = params[:image][:remote_upload_url]
  valid = true
rescue CarrierWave::DownloadError
  @image.errors.add(:remote_upload_url, "This url doesn't appear to be valid")
rescue CarrierWave::IntegrityError
  @image.errors.add(:remote_upload_url, "This url does not appear to point to a valid image")
end 

# validate and save if no exceptions were thrown above
if valid && @image.save
  redirect_to(images_configure_path)
else
 render :action => 'new'
end
Run Code Online (Sandbox Code Playgroud)

基本上,我将构造函数包装在一个救援块中,并初始设置除远程URL之外的所有参数.当我设置它时,可能会发生异常,我通过手动设置模型中的错误来处理.请注意,在此方案中不执行其他验证.这是一个黑客,但为我工作.

我希望通过将资源下载延迟到模型验证阶段或之后,可以在将来的版本中解决这个问题.


Dav*_*ite 0

此问题的解决方案已添加到Github 上的CarrierWave Wiki中。

编辑:
我现在正在尝试实施建议的解决方案,但无法使其正常工作。我正在使用 AR on Rails 3.1.3。

按照 wiki 上的方式实现代码会导致验证实际上顺利进行。当我尝试上传乱码时,我收到一条很好的验证消息。问题是正常上传也被阻止。