如何在Carrierwave中指定验证顺序?

时间:2015-08-11 19:50:10

标签: ruby-on-rails carrierwave

我正在使用Carrierwave并尝试验证上传图片的大小,并且只允许这些文件扩展名:jpg jpeg png

这本身可以正常使用

def extension_white_list
    %w(jpg jpeg png)
end

此验证工作正常

def validate_image_dimensions
  minDim = 320
  maxDim = 3840

  puts screenshot.path
  image = MiniMagick::Image.open(screenshot.path)

  largestDim = [image[:width], image[:height]].max
  smallestDim = [image[:width], image[:height]].min

  unless largestDim <= smallestDim * 2
    errors.add :screenshot, "maximum dimension of screenshot cannot be more than twice as long as the minimum dimension"
  end

  #image must be either 320x480, 480x854, 1280x720, 1280x800
  unless (image[:width] == 320 && image[:height] == 480) || (image[:width] == 480 && image[:height] == 800) || (image[:width] == 480 && image[:height] == 854) || (image[:width] == 1280 && image[:height] == 720) || (image[:width] == 1280 && image[:height] == 800)
    errors.add :screenshot, "Screenshots must have one of these dimensions: 320x480, 480x854, 1280x720, or 1280x800"
  end

  unless image[:width] >= minDim && image[:height] >= minDim && image[:width] <= maxDim && image[:height]
    errors.add :screenshot, "Minimum screenshot dimension is #{minDim}px and maximum screenshot dimension is #{maxDim}px" 
  end
end

但是当我同时使用它们并尝试上传不在extension_white_list中的扩展名的文件时,就像.mkv文件一样,我的validate_image_dimensions验证中出现错误。该行引发了错误 image = MiniMagick::Image.open(screenshot.path) 因为MiniMagick正在尝试打开图像文件,但我给它一个.mkv文件。

有没有办法让Carrierwave首先检查文件是否有有效的扩展名,然后运行我的验证?现在,它似乎正在运行我的验证,然后检查扩展是否有效。

一种解决方案是在运行validate_image_dimensions验证之前检查文件是否是图像,但似乎Carrierwave应该先做之前检查文件是否为有效类型。

1 个答案:

答案 0 :(得分:1)

不幸的是,没有办法订购验证。自定义验证应该能够处理其他属性无效而不会抛出错误。在您的情况下,如果您根本没有图像,则检查图像的有效性是没有意义的,因此您需要检查该文件是否为自定义验证开始时的图像。如果扩展程序不在白名单中,return最简单的方法是执行此操作:

return unless extension.in? extension_white_list

由于扩展验证,记录仍然无效,因此无论如何都不会保存。

ETA 我在假设您的模型上定义了extension或类似方法的情况下编写了上述内容。如果您无法访问文件扩展名,则始终可以从错误中rescue。您没有指定MiniMagick::Image.open行引发的错误。我们暂时说它是MiniMagick::ImageException。然后你可以:

def validate_image_dimensions
  …
  image = MiniMagick::Image.open(screenshot.path)
  …
rescue MiniMagick::ImageException => e
  Rails.logger.info "Rescued from MiniMagick::ImageException in validation: #{e.message}"
  errors.add :screenshot, "is not a valid image"
end