簡體   English   中英

使用Carrierwave重命名上傳的文件

[英]Renaming uploaded files with Carrierwave

我正在使用Carrierwave上傳文件,我有它的工作。

我的問題是嘗試更改上傳文件的名稱。

在生成的uploader.rb中有一個我認為我應該使用的方法

def filename
   "something.jpg" if original_filename
   basename = "what"+orginal_filename if original_filename, works
   basename = (0...8).map{65.+(rand(25)).chr}.join if original_filename  # will create a random name for each version, e.g. the orginal, the thumb, and the filename in the db, useless
 end

我似乎無法訪問sanitized_file.rb中的'extension'或'content_type'之類的項目,因此這有點超出我目前的技能水平。

這樣做的任何建議或練習,即為上傳的文件生成文件名,該文件與carrierwave默認值一樣(什么都不做,但是會繼續執行每個版本)? 看起來它應該很簡單,但我偶然發現了這一點。

那么,隨機文件名生成器的另一個問題是它可能發生沖突不是嗎? 您可能會生成已生成的文件名。 一種方法是以某種方式基於圖像的唯一屬性(如文件路徑)生成哈希。 來自carrierwave 集團的一個例子:

def filename 
  if original_filename 
    @name ||= Digest::MD5.hexdigest(File.dirname(current_path))
    "#{@name}.#{file.extension}"
  end
end

這將基於當前路徑創建MD5哈希,然后將原始文件的擴展名附加到其上。

編輯: carrierwave wiki添加了一個條目,其中包含一些有關如何為所有版本化文件創建隨機和唯一文件名的方法。

要擁有一個真正獨特的文件名(幾乎不是唯一的)我建議使用uuid gem。

在Gemfile中添加:

gem 'uuid'

在file_uploader.rb中:

def filename
  if original_filename
    if model && model.read_attribute(mounted_as).present?
      model.read_attribute(mounted_as)
    else
      @name ||= "#{mounted_as}-#{uuid}.#{file.extension}"
    end
  end
end

protected

def uuid
  UUID.state_file = false
  uuid = UUID.new
  uuid.generate
end

另一個解決方案看起來不錯,但我是如何做到的,那就是在實例創建時為一個新名稱創建一個隨機字符串,然后:

 def filename
    "#{model.randomstring}.#{model.image.file.extension}"
 end

在上傳者。

這很有效,將隨機名稱生成作為模型的一部分,然后讓載波使用它。

我很好奇哪個更快,更有效,更合理,更合理,等等。

來自Google群組

def filename
  @name ||= "#{secure_token}.#{file.extension}" if original_filename
end

private

def secure_token
  ivar = "@#{mounted_as}_secure_token"
  token = model.instance_variable_get(ivar)
  token ||= model.instance_variable_set(ivar, ActiveSupport::SecureRandom.hex(4))  
end

要使record.id前綴為文件名,您可以執行以下操作:

class MyUploader < CarrierWave::Uploader::Base

  storage :file

  def store_dir
    model.class.to_s.underscore.pluralize
  end

  def filename
    model.id ? "#{model.id}-#{original_filename}" : original_filename
  end

  def url
    "/#{store_dir}/#{model.id}-#{model.file_before_type_cast}"
  end
end

這是解決方案,如何更改文件的名稱,如果store_dir已經包含具有確切名稱的文件:

  if File.exists?(Rails.root.join("documents/" + "#{file.filename}")) && !path.to_s.eql?(Rails.root.join("documents/" + original_filename).to_s)
    @name ||= File.basename(original_filename, '.*') + Digest::MD5.hexdigest(File.dirname(current_path)).from(25)
    "#{@name}.#{file.extension}"
  else
    "#{original_filename}"
  end

注意Rails.root.join("documents/")被定義為我的store_dir

希望它可以幫助某人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM