How to validate a file extension only if there is a file extension? Re: carrierwave
Asked Answered
E

3

7

I am using CarrierWave, and I would like to validate file names and only allow file uploads if the extension is .gif, .png, .jpg, .jpeg, or if there is no file extension.

Sometimes users upload files with no extensions. For example:

http://t2.gstatic.com/images?q=tbn:ANd9GcTCD2TLvYI8a4ChgBaYK_JaRfedvXLr3HXQfj0arXXAii3o2yjf

I am aware of the possibility of uncommenting the following lines in uploaders/image_uploader.rb, but I don't know of a way of additionally saying "allow any of these extensions only if there is a file extension".

# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
#def extension_white_list
#  %w(gif jpg jpeg png)
#end

As well, in my model I have a validation as follows, but for some reason bad-extension.bad passes.

validates :image, allow_blank: true, format: {
    with: %r{\.(gif|jpe?g|png)\z}i,
    message: 'must be a GIF, JPG, or PNG'
}, if: :filename_has_extension?

def filename_has_extension?
  image =~ /\./
end
Euphemize answered 29/8, 2012 at 18:41 Comment(0)
A
2

Well Why not use Mimetype comparison of the file in validation process there is ruby gem call mimetype that can help you in your quest

something like this

AVAILABLE_MIMETYPE = %w(image/gif)

validate :mime_type_of ,:if => :if_changed?


private
def mime_type_of
  AVAILABLE::MIMETYPE.include?(MIME::Types.type_for[image_path][0]) 
end

def if_changed?
  new_record? or image_changed?
end

Even CarrierWave Include MimeType Gem Internally check if that can help too

Hope this Help

Aluino answered 30/8, 2012 at 17:27 Comment(0)
E
0

image is not a String, rather it's of the class ImageUploader (class ImageUploader < CarrierWave::Uploader::Base).

Therefore this line is at fault:

image =~ /\./

Correct it by converting it to a String:

image.to_s =~ /\./

That said, a better expression would be:

!(image.to_s =~ /\.[a-z]{1,4}\z/).nil?

It makes sure that the extension consists of one to four a-z characters. Also, =~ returns nil if nothing is found, and this line takes that into account.

If an extension is not found, =~ returns nil; so .nil? will return true; and ! will invert it to false; thus indicating that there is no extension.

If on the other hand there is an extension, =~ returns the position the match starts; which is 0 or greater, which is not nil; so .nil? will return false; and when inverted by !, true is returned; thus indicating that there is an extension.

Euphemize answered 29/8, 2012 at 22:15 Comment(0)
S
0

in my case I just change in my avatar_uploader.rb:

  def extension_white_list
    %w(jpg jpeg gif png) if model.avatar.file.extension.present?
  end

:)

Stuppy answered 8/7, 2016 at 19:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.