Carrierwave file upload with different file types

2019-03-19 19:46发布

问题:

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`

回答1:

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


回答2:

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.



回答3:

Try to use if within process, e.g.

process :action, :if => :image?

Related: Conditional versions/process with Carrierwave