How can I make CarrierWave add correct extension to filename depending on its contents? For example, if I upload file \"logo\" (PNG file without extension) CarrierWave shoul
The problem is in determining the correct content in the first place. Carrierwave uses the MimeType gem which determines its mime-type from the extension. Since, in your case the extension is incorrect you need an alternate way of getting the correct mime-type. This is the best solution I was able to come up with, but it depends on the ability to read the image file using the RMagick gem.
I ran into this same problem and had to override the default set_content_type method for my uploader. This assumes you have Rmagick gem in your Gemfile, so that you can get the correct mime-type from reading the image, as opposed to making a best guess.
Note: This is particularly useful if the image is being used by Prawn which supports only JPG and PNG images.
Uploader Class:
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
Image Model:
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
In your case you can add an additional method that changes the extension based on this correct mime-type (content_type).