Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Carrierwave file upload with different file types

I have the following as my FileUploader:

class FileUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  version :thumb, if: :image? do
    # For images, do stuff here
  end

  version :preview, if: :pdf? do
     # For pdf, do stuff here
  end

  protected

  def image?(new_file)
    new_file.content_type.start_with? 'image'
  end

  def pdf?(new_file)
    new_file.content_type.start_with? 'application'
  end

end

I got this from the carrierwave github page. It mostly works, but what If I don't want different versions? I basically just want to do certain processes if it's a pdf, or certain processes if it's an image. I may allow other types of files in the future as well, so it'd be cool if I could have an easy way to do that as well.

For an example, I may want to use an imgoptim if it's an image, and then a pdf optimizing library if it's a pdf, etc.

I tried:

if file.content_type = "application/pdf"
    # Do pdf things
elsif file.content_type.start_with? 'image'
    # Do image things
end

but get the error: NameError: (undefined local variable or methodfile' for FileUploader:Class`

like image 682
Muhambi Avatar asked Jun 07 '15 21:06

Muhambi


3 Answers

You should try using like this

class FileUploader < CarrierWave::Uploader::Base  
  include CarrierWave::MiniMagick

  process :process_image, if: :image?
  process :process_pdf, if: :pdf?

  protected

  def image?(new_file)
    new_file.content_type.start_with? 'image'
  end

  def pdf?(new_file)
    new_file.content_type.start_with? 'application'
  end

  def process_image
    # I process image here
  end

  def process_pdf
    # I process pdf here
  end
end
like image 90
Ojash Avatar answered Nov 02 '22 15:11

Ojash


The exception indicates that you are calling a instance variable at the Class level scope. Add a debugger breakpoint and print out self you will understand what is going on.

Solution to this is to wrap you logic into a instance method, and use this method as default process.

process :process_file

def process_file
  if file.content_type = "application/pdf"
      # Do pdf things
  elsif file.content_type.start_with? 'image'
      # Do image things
  end
end

By doing this, you can get rid of versions you don't need, and process whatever you want based on mime types.

like image 45
Jason Huang Avatar answered Nov 02 '22 13:11

Jason Huang


Try to use if within process, e.g.

process :action, :if => :image?

Related: Conditional versions/process with Carrierwave

like image 36
shlajin Avatar answered Nov 02 '22 13:11

shlajin