ruby-on-rails - 我该怎么办 :remote location validation with CarrierWave?

标签 ruby-on-rails ruby ruby-on-rails-3 validation carrierwave

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

CarrierWave::DownloadError in ImageController#create
trying to download a file which is not served over HTTP

这是我的模型:

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

这是我的 Controller :

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

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

最佳答案

我遇到了同样的问题。不幸的是,这看起来像是 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

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

我希望这可以在未来的版本中解决,方法是将资源下载延迟到模型验证阶段或之后。

关于ruby-on-rails - 我该怎么办 :remote location validation with CarrierWave?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6012677/

相关文章:

ruby-on-rails - ruby on rails has_many(和类似的)是如何实现的?

ruby-on-rails - Rails 3 - 两个子域不同范围的同一 Controller

ruby-on-rails - 'belongs_to` 关联上的自动保存无法保存关联模型

ruby-on-rails - Ruby bundler 身份验证错误

ruby - 从 war 文件中运行 rake 任务

ruby-on-rails - 在 Rails 模型中添加公共(public)变量?

ruby-on-rails - Rails url 助手在 Rspec 中不起作用

ruby-on-rails - 是否可以从 Rails 应用程序中访问 DataDog trace_id

ruby-on-rails - Rails 找不到刚创建的数据库列

ruby - sprintf 格式不符合预期