[英]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.