第一次使用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