Carrierwave: Move version name to end of filename, instead of front

1.1k views Asked by At

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

There are 3 answers

4
itsnikolay On BEST ANSWER

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
8
Bharat soni On

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.

0
JP Duffy On

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