CarrierWave: Create the same, unique filename for all versioned files

You can do something like this in your uploader file, and it will also work for versioned files (i.e. if you have one image and then create 3 other thumbnail versions of the same file, they will all have the same name, just with size info appended onto the name):

  # Set the filename for versioned files
  def filename
    random_token = Digest::SHA2.hexdigest("#{Time.now.utc}--#{model.id.to_s}").first(20)
    ivar = "@#{mounted_as}_secure_token"    
    token = model.instance_variable_get(ivar)
    token ||= model.instance_variable_set(ivar, random_token)
    "#{model.id}_#{token}.jpg" if original_filename
  end

This will create a filename like this for example: 76_a9snx8b81js8kx81kx92.jpg where 76 is the model's id and the other bit is a random SHA hex.


Check also the solution from carrierwave wiki available now https://github.com/carrierwaveuploader/carrierwave/wiki/How-to:-Use-a-timestamp-in-file-names

You can include a timestamp in filenames overriding the filename as you can read in Carrierwave docs:

 class PhotoUploader < CarrierWave::Uploader::Base
     def filename
       @name ||= "#{timestamp}-#{super}" if original_filename.present? and 
       super.present?
    end

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

Don't forget to memorize the result in an instance variable or you might get different timestamps written to the database and the file store.