我正在使用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默认值一样(不执行任何操作,但会继续执行每个版本)?似乎它应该足够简单,但我偶然发现了这一点。
答案 0 :(得分:34)
那么,你的随机文件名生成器的另一个问题是它可能会发生冲突吗?您可能会生成已生成的文件名。 一种方法是以某种方式基于图像的唯一属性(如文件路径)生成哈希。例如,来自carrierwave group:
def filename
if original_filename
@name ||= Digest::MD5.hexdigest(File.dirname(current_path))
"#{@name}.#{file.extension}"
end
end
这将根据当前路径创建MD5哈希,然后将原始文件的扩展名附加到其上。
编辑:carrierwave wiki添加了一个entry,其中包含一些有关如何为所有版本化文件创建随机和唯一文件名的方法。
答案 1 :(得分:5)
要拥有真正独特的文件名(几乎不是唯一的)我建议使用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
答案 2 :(得分:1)
另一个解决方案看起来很不错,但我是如何做的就是在实例创建时为一个新名称创建一个随机字符串,然后:
def filename
"#{model.randomstring}.#{model.image.file.extension}"
end
在上传器中。
这很有效,将随机名称生成作为模型的一部分,然后让carrierwave使用它。
我很好奇哪个更快,更有效,更合理,更健全等。
答案 3 :(得分:1)
来自Google Group:
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
答案 4 :(得分:1)
要将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
答案 5 :(得分:0)
以下是解决方案,如果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
。
希望它有所帮助。