carrierwave:拒绝.gif重命名为.jpg

时间:2013-01-24 03:32:15

标签: ruby-on-rails ruby-on-rails-3 carrierwave rmagick

我希望允许用户上传.jpg个文件,但前提是它们实际上是.jpg(例如,cat.gif重命名为cat.jpg 工作。

目前在我的Carrierwave ImageUploader.rb中我有:

include CarrierWave::RMagick
include CarrierWave::MimeTypes
process :set_content_type
def extension_white_list
  %w(jpg jpeg png)
end

在我的Rspec测试文件中,我测试了三种方式:

# Works
describe "with invalid mime type and invalid extension" do
  before do
    image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'executable.jpg')) # this is a .exe renamed to .jpg
  end
  it { image.should_not be_valid }
end

# Works
describe "with invalid mime type and invalid extension" do
  before do
    image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'test_gif.gif')) # this is a .gif
  end
  it { should_not be_valid }
end

# Doesn't work
describe "with invalid mime type and valid extension" do
  before do
    image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'test_gif.jpg')) # this is a .gif renamed to .jpg
  end
  it { image.should_not be_valid }
end

前两个测试通过,但第二个测试失败。我不知道为什么,因为我在白名单上没有gif而且我正在检查mime类型。

有什么建议吗?

(将gif转换为jpgs是我的备份,但我宁愿拒绝它们。)

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,不得不覆盖我的上传者的默认set_content_type方法。这假设您的Gemfile中有 Rmagick gem,这样您就可以通过阅读图像获得正确的mime类型,而不是做出最佳猜测。

注意:如果Prawn正在使用仅支持JPG和PNG图像的图像,这将非常有用。

上传者类:

process :set_content_type

def set_content_type #Note we are overriding the default set_content_type_method for this uploader
  real_content_type = Magick::Image::read(file.path).first.mime_type
  if file.respond_to?(:content_type=)
    file.content_type = real_content_type
  else
    file.instance_variable_set(:@content_type, real_content_type)
  end
end

图片模型:

class Image < ActiveRecord::Base
  mount_uploader :image, ImageUploader

  validates_presence_of :image
  validate :validate_content_type_correctly

  before_validation :update_image_attributes

private
  def update_image_attributes
    if image.present? && image_changed?
      self.content_type = image.file.content_type
    end
  end

  def validate_content_type_correctly
    if not ['image/png', 'image/jpg'].include?(content_type)
      errors.add_to_base "Image format is not a valid JPEG or PNG."
      return false
    else
      return true
    end
  end
end