skip to Main Content

Currently with Carrierwave, after uploading a file like foo.png when creating different versions like so:

class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  storage :fog
  def store_dir
    "#{model.class.to_s.underscore}/#{model.id}"
  end

  version :thumb do
    process :resize_to_fit => [500, 500]
  end
end

that results in the files being uploaded as:

thumb_foo.png
foo.png

I want to move “thumb” to the end of the filename for SEO reasons. Based on their docs here I added:

  def full_filename(for_file)
    if parent_name = super(for_file)
      extension = File.extname(parent_name)
      base_name = parent_name.chomp(extension)
      [base_name, version_name].compact.join("_") + extension
    end
  end

  def full_original_filename
    parent_name = super
    extension = File.extname(parent_name)
    base_name = parent_name.chomp(extension)
    [base_name, version_name].compact.join("_") + extension
  end

The docs say this should result in:

foo_thumb.png
foo.png

However, I end up actually getting the following:

thumb_foo_thumb.png
foo.png

Any idea what I’m doing wrong?

3

Answers


  1. In the current version of CarrierWave if you have an uploader defined like this:

    class LogoUploader < CarrierWave::Uploader::Base 
      # ... 
      def filename 
        "original_#{model.logo.file.extension}" if original_filename 
      end 
      version :small do 
        process :resize_to_fit => [190, 190] 
        process :convert => 'png' 
      end 
      version :icon do 
        process :resize_to_fill => [50, 50] 
        process :convert => 'png' 
      end 
      # ... 
    end
    

    and attach a file name somefile.jpg, you will end up with files named original.jpg, original_small.png and original_icon.png respectively.

    Login or Signup to reply.
  2. Simply use #full_filename under the version block:

    class AvatarUploaer < CarrierWave::Uploader::Base
      include CarrierWave::MiniMagick
    
      storage :file
    
      version :thumb do
        process resize_to_fill: [50, 50]
    
        def full_filename(for_file = model.logo.file)
          parts     = for_file.split('.')
          extension = parts[-1]
          name      = parts[0...-1].join('.')
          "#{name}_#{version_name}.#{extension}"
        end
      end
    end
    

    The result will be following:

    /Users/user/app/uploads/1x1.gif
    /Users/user/app/uploads/1x1_thumb.gif
    
    Login or Signup to reply.
  3. If you have a lot of versions, the accepted answer can get a little tedious.

    I ended up overriding full_filename for everything instead of in each individual version definition. It works fine. This is for Carrierwave 1.0

    photo_uploader.rb

    # Override the filename of the uploaded files:
    def full_filename(name)
      "#{File.basename(name, '.*')}_#{version_name || 'original'}#{File.extname(name)}"
    end
    

    I’m using the built in File.basename and File.extname methods instead of doing it manually as seen in the accepted answer (although that’s where I started and that code works fine too).

    Note: I wanted to add "original" to the unversioned upload just so my directory listing looked cleaner. That part could be removed fairly easily.

    foo_mobile.jpg

    foo_original.jpg

    foo_square.jpg

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search