0

I have thousands of images uploaded with the following filename structure.

def filename
 "#{model.id}" + "-v#{timestamp}" + "-" + Category.find("#{model.category_id}").slug + "-" + CategoryItem.find("#{model.category_item_id}").slug + ".png" if original_filename.present?
end

def timestamp
    var = :"@#{mounted_as}_timestamp"
    model.instance_variable_get(var) or model.instance_variable_set(var, Time.now.to_i)
end

I need to create thumbs for all the images to speed up certain page load times. I've setup the thumb version in the uploader file

  # Create different versions of your uploaded files:
   version :thumb do
     process :resize_to_limit => [110, nil]
   end

but now when I run: CategoryItem.each {|item| item.image_value.recreate_versions! if item.image_value? }

The thumb is created but the filename of the thumb image isn't the same as the original file with beyond the added 'thumb_' at the start of the filename.

saved filename: 1-v1474175808-shoes-runners.png

thumb filename: thumb_1-v1472111618-shoes-runners.png (different timestamp)

CategoryItem.find(1).image_value_url(:thumb): thumb_1-v1474175808-shoes-runners.png (original filename timestamp)

So calling image_tag CategoryItem.find(1).image_value_url(:thumb) looks for a file that doesn't exist.

How can I run recreate_versions and have the thumb filename be the same as the original saved filename but with 'thumb_' added to the front without removing the timestamp?

Update:

I now have the following from finding this https://github.com/carrierwaveuploader/carrierwave/wiki/How-to:-Customize-your-version-file-names

 version :thumb do
     process :resize_to_limit => [110, nil]

     def full_filename(for_file = model.image_value.file)
     'thumb_' + File.basename(model.image_value.path).to_s
     end
   end

my problem is that even though I'm calling the direct filename File.basename(model.image_value.path).to_s, when I run recreate_versions it still saves the file with the current timestamp in it rather than grabbing the original filename. I thought maybe the filename is changing in the DB and its grabbing the new filename but it is staying the same as expected so I have no idea why it isnt grabbing the direct value from the db and not making a random timestamp in the name.

Also I though maybe def full_filename(for_file = model.image_value.file) isnt working but if I change it to

 version :thumb do
     process :resize_to_limit => [110, nil]

     def full_filename(for_file = model.image_value.file)
     'thumb_' + "random-text"
     end
   end

the thumb image is saved as 'thumb_random-text' so it is running through that code

Rob
  • 1,835
  • 2
  • 25
  • 53

3 Answers3

0

add following method to your Uploader class

def timestamp
  model.created_at
end

def filename
  # custom name, or you can debug this first
end

version :thumb do

  def full_filename(for_file = model)
    'thumb_' + filename
  end

  def filename
    # custom name, or you can debug this first
  end

end
Saiqul Haq
  • 2,287
  • 16
  • 18
  • It still saves with the a current timestamp not the filename of the original image. I tired '`thumb_' + model.image_value.to_s` but it uses the whole url – Rob Sep 18 '16 at 09:58
  • can you clarify why you include the timestamp in the filename? – Saiqul Haq Sep 18 '16 at 10:09
  • The timestamp method is directly from the carrierwave docs. I've added `'thumb_' + File.basename(model.image_value.path).to_s` from reading http://stackoverflow.com/questions/5132847/displaying-a-carrierwave-filename-in-the-view. `File.basename(model.image_value.path).to_s` grabs the exact filename saved in the db but it still it gives it the current timestamp in the filename saved and doesn't directly copy the file name from the db. – Rob Sep 18 '16 at 11:21
  • If I make the thumb name something like 'thumb_skdnsdkjn' it saves it directly like that when running `recreate_versions` but using the string `File.basename(model.image_value.path).to_s` for some reason doesn't grab the name from the DB but looks like it runs through the original `def filename` method or something – Rob Sep 18 '16 at 11:25
  • I've updated my question with what I have and what my problem is right now. – Rob Sep 18 '16 at 11:46
  • how about overriding the filename method? check my answer above – Saiqul Haq Sep 18 '16 at 11:51
0

I was having the same issue and found a workaround which fits my needs.

First, you need store the original filename in your db when you upload a photo: https://github.com/carrierwaveuploader/carrierwave/wiki/how-to:-create-random-and-unique-filenames-for-all-versioned-files#saving-the-original-filename

Then, because the thumb version is created after the original version, when I define the thumb's filename I look for a photo with the same original_filename in that model (product_review_photo in my case) and get the timestamp from its url with regex. I then simply use this timestamp to create my thumb's filename - this way the original and thumb both have the same timestamp.

This is how I name my origin files:

"#{model.product_review.id}_#{Time.now.to_f.to_s.delete('.')}.#{uploaded_file.extension}"

And this is how I name my thumb images:

version :thumb do
  process resize_to_fill: [200, 200]

  def filename(uploaded_file = file)
    model.product_review.product.name + '_' + model.product_review.product_review_photos.find_by(original_filename: original_filename).photo.url.match(/_(\d{10,})/)[1] + '.' + uploaded_file.extension  
  end
end
benj-p
  • 405
  • 2
  • 10
0

Everything is shown here. https://github.com/carrierwaveuploader/carrierwave/wiki/how-to:-create-random-and-unique-filenames-for-all-versioned-files#note

You can use same filename when you execute carrierwave recreate_versions!.

class AvatarUploader < CarrierWave::Uploader::Base
  def filename
    if original_filename
      if model && model.read_attribute(mounted_as).present?
        model.read_attribute(mounted_as)
      else
        # new filename
      end
    end
  end
end
Kome
  • 46
  • 3