使用CarrierWave上传图片时,多版本文件名的统一

第一次使用CarrierWavewe做上传,不能不说,虽然Rails已经把上传变得超简单了,而CarrierWave则是把上传变成了一种享受,特别是做图片上传,现在这年代,图片展示平台已经不仅仅是电脑了,各移动端也是必须要兼顾的,这导致了上传的图片,一般都需要有好几个版本大小,如果还纯手工的使用RMagick之类慢慢处理的话,实在是有点郁闷,而CarrierWave配上MiniMagick,一个version搞定一切,真的是感觉“倍儿爽”。

不过在使用过程中,也发现了几个小问题,最主要的就是,就是当存在多个图片大小版本时,生成的文件名不一致的情况。CarrierWave本身生成文件名是使用时间戳的,但是当存在多个版本时,第一个版本,它都会启动一个新实例,这导致生成的文件名,时间上会不一样,也就导致了了最终的文件名不一样。

网上搜索了一下,比较好和方便的是大牛李华顺的方法,利用临时文件路径中的时间戳来做MD5,得到一致的文件名。不过我这次要求的文件名格式不一样,要求如下:

用户ID_时间_随机数.后缀

经过多次尝试,用了一个不怎么漂亮的方式实现了

class ShopImgUploader < CarrierWave::Uploader::Base	
	include CarrierWave::MiniMagick
	
	process :resize_to_fit =>[500,500]
	
	version :thumb do
		process :resize_to_fill => [200,200]
	end
	
	#关键,添加一个方法,直接设置文件名
	#我这里的p就是用户ID,而加上name是因为每个新的version都会启动一个新实例
	#新实例中,是没有@name的,所以我们在生成文件名的时候,强制调用一下
	def set_prefix p,name=nil
		@prefix = p
		if name.nil?
			@name = "#{@prefix}_#{Time.now.strftime '%Y%m%d%H%M%S%L'}_#{rand(1..100)}"
		else
			@name = name
		end
	end

	#生成文件名规则
	def filename
		#只有原始文件实例的时候@versions才不为空,所以不会重复调用
		unless @versions.nil?
			@versions.each do |version,obj|
				#很粗暴的直接指定名称,各版本会在名称前加上版本前缀,比如thumb_
				obj.set_prefix(@prefix, @name)
			end
		end
		"#{@name}.#{file.extension}"
	end

end

  

原文地址:https://www.cnblogs.com/varlxj/p/carrierwave_file_name.html