微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby-on-rails – Carrierwave预先计算文件的md5校验和作为文件名

使用载波上传获取图像,尝试使用md5校验和作为文件名提供上传图像的唯一性

看起来我做错了什么

模型定义如下:

class Image < ActiveRecord::Base
  attr_accessible :description,:img
  mount_uploader :img,ImageUploader

我的上传代码如下:

class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file

def store_dir
  "images/#{filename[0,2]}"
end

def md5
  @md5 ||= ::Digest::MD5.file(current_path).hexdigest
end

def filename
  @name ||= "#{md5}#{::File.extname(current_path)}" if super
end

首先,我怀疑这种方法在每次查询图像输入时都会对校验和进行计算

其次,保存图像输入后,img.original_filename img.filename img.path img.current_path中的每个其他似乎都未定义,并出现以下错误

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
app/uploaders/image_uploader.rb:17:in `store_dir'
carrierwave (0.5.7) lib/carrierwave/uploader/store.rb:43:in `store_path'
carrierwave (0.5.7) lib/carrierwave/storage/file.rb:41:in `retrieve!'
carrierwave (0.5.7) lib/carrierwave/uploader/store.rb:95:in `block in retrieve_from_store!'
carrierwave (0.5.7) lib/carrierwave/uploader/callbacks.rb:17:in `with_callbacks'
carrierwave (0.5.7) lib/carrierwave/uploader/store.rb:94:in `retrieve_from_store!'
carrierwave (0.5.7) lib/carrierwave/mount.rb:311:in `uploader'

任何形式的帮助或提示表示赞赏

UPD:

以这种方式改变了上传者:

def store_dir
  "images/#{model.img_identifier[0,2]}"
end

def filename
  @name ||= "#{md5}#{::File.extname(current_path)}"
end

protected
def md5
  var = :"@#{mounted_as}_md5"
  model.instance_variable_get(var) or model.instance_variable_set(var,::Digest::MD5.file(current_path).hexdigest)
end

current_path似乎引用了form-submitted tempfile的完整路径,因此对扩展提取摘要计算有效
img_identifier代表持久生成文件名,因此对于store_dir的前缀提取有效
仍然不确定这种方法是否引起任何警告

仍然不相信应该执行文件唯一性验证的方式

UPD:

我在我的模型类中添加了这个before_validation回调:

validates_uniqueness_of :checksum
before_validation :assign_checksum

def assign_checksum
  self.checksum = img.md5 if img.present? and img_changed?
end

其中校验和是我模型的db表中的单独字符串字段
它是非常多余的,因为它一般复制img字段,但我仍然无法弄清楚验证img本身的唯一性的方法.

UPD:

以这种方式远离数据库冗余.在我的模型中:

validate :img_uniqueness

def img_uniqueness
  errors.add :img,"Image already exists in database" if Image.where(:img => self.img.filename).first
end

现在没有必要在校验和领域

解决方法

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐