Awjeccの完備録

Railsメインのエンジニアブログ、GoogleとAmazonが大好き

Carrierwave uploading multiple files and generating unique filenames with their dimensions

f:id:awjecc:20161212123706p:plain

Carrierwave v1.0.0 supported uploading multiple files.

Problem

But all of the files generated by this secure_token method will be given the same filename.

  def filename
    "#{secure_token}.#{file.extension}" if original_filename.present?
  end

  def secure_token
    var = :"@#{mounted_as}_secure_token"
    model.instance_variable_get(var) || model.instance_variable_set(var, size_with_random)
  end

OUTPUT:

> article.images.map(&:path).map { |u| u.scan(/[^\/]*$/) }
=> [["077a7d72-0f85-480b-8252-c0fd8ebc1112.jpg"], ["077a7d72-0f85-480b-8252-c0fd8ebc1112.jpg"]]

secure_token method generates one filename for one model instance, so we can't use it anymore.

Solution

EDIT: Solved problem, and filename will contain it's image dimensions, like "x_.".

  def filename
    if original_filename.present?
      return @filename if @filename && @filename != original_filename
      if self.parent_version.nil?
        width, height = ::MiniMagick::Image.open(file.file)[:dimensions]
        @filename = "#{width}x#{height}_#{SecureRandom.uuid}.#{file.extension}"
      else 
        self.parent_version.filename
      end
    end
  end

OUTPUT:

> article.images.map(&:path).map { |u| u.scan(/[^\/]*$/) }
=> [["800x600_077a7d72-0f85-480b-8252-c0fd8ebc1112.jpg"], ["800x600_40f73be0-661b-4da4-b26a-5d3ad155ce12.jpg"]]