Rails:使用Paperclip防止重复的照片上传?

时间:2010-03-16 20:56:10

标签: ruby-on-rails paperclip

如果用户尝试使用Paperclip将同一张照片两次上传到Rails应用程序,是否会抛出验证错误? Paperclip似乎没有提供此功能......

我正在使用Rails 2.3.5和Paperclip(显然)。


解决方案:(或至少其中一个)

根据Beerlington的建议,我决定采用MD5校验和比较:

class Photo < ActiveRecord::Base
  #...
  has_attached_file :image #, ...

  before_validation_on_create :generate_md5_checksum
  validate :unique_photo
  #...

  def generate_md5_checksum
    self.md5_checksum = Digest::MD5.hexdigest(image.to_file.read)
  end

  def unique_photo
    photo_digest = self.md5_checksum
    errors.add_to_base "You have already uploaded that file!" unless User.find(self.user_id).photos.find_by_md5_checksum(photo_digest).nil?
  end

  # ...
end

然后我在我的photos表中添加了一个名为md5_checksum的列,瞧!现在,如果您尝试上传同一张照片,我的应用会抛出验证错误!

不知道这是多么高效/低效,所以重构是受欢迎的!

谢谢!

4 个答案:

答案 0 :(得分:11)

在图像文件上执行MD5怎么样?如果它是完全相同的文件,则两个图像的MD5哈希值相同。

答案 1 :(得分:10)

对于任何试图这样做的人。 Paperclip现在内置了md5哈希。如果你的模型中有[attachment] _fingerprint,回形针将用MD5填充。

由于我已经有一个名为hash_value的列,因此我创建了一个名为fingerprint

的“虚拟”属性
#Virtual attribute to have paperclip generate the md5
def picture_fingerprint
  self.hash_value
end

def picture_fingerprint=(md5Hash)
  self.hash_value=md5Hash
end

而且,使用rails3,使用sexy_validations,我可以简单地将它添加到我的模型顶部,以确保hash_value在保存模型之前是唯一的:

validates :hash_value, :uniqueness => { :message => "Image has already been uploaded." }

答案 2 :(得分:3)

当您的图片修改了EXIF元数据时,您可能会遇到问题。这发生在我身上,我不得不提取像素值并从中计算MD5,忽略Wordpress等所做的更改。您可以在我们的博客上阅读它:http://www.amberbit.com/blog/2013/12/20/similar-images-detection-in-ruby-with-phash/但实质上您想要获取像素数据使用某些工具(如RMagick)将图像缩小为字符串,然后计算MD5。

答案 3 :(得分:0)

斯蒂芬指出,你最大的问题是如何确定文件是否重复,并且没有明确的答案。

如果这些是使用数码相机拍摄的照片,则需要比较EXIF数据。如果EXIF数据匹配,那么照片很可能是重复的。如果它是重复的,那么您可以通知用户。您最初必须接受上传,以便检查EXIF数据。

我应该提一下,EXIFR是检查EXIF数据的不错的宝石。

相关问题