如何使用Paperclip保存原始数据照片

6

我正在使用jpegcam,允许用户拍摄网络摄像头照片并将其设置为其个人资料照片。该库最终会将原始数据发布到服务器上,我可以在我的Rails控制器中获取这些数据,如下所示:

def ajax_photo_upload
  # Rails.logger.info request.raw_post
  @user = User.find(current_user.id)
  @user.picture = File.new(request.raw_post)

当您尝试保存request.raw_post时,它不能正常工作,而且paperclip/rails也会失败。

Errno::ENOENT (No such file or directory - ????JFIF???

我看到过一些解决方案可以创建一个临时文件,但我很好奇是否有一种方法可以让Paperclip自动保存request.raw_post而不必创建临时文件。是否有优雅的想法或解决方案? < p > < strong > 丑陋的解决方案(需要临时文件)

class ApiV1::UsersController < ApiV1::APIController

  def create
    File.open(upload_path, 'w:ASCII-8BIT') do |f|
      f.write request.raw_post
    end
    current_user.photo = File.open(upload_path)
  end

 private

  def upload_path # is used in upload and create
    file_name = 'temp.jpg'
    File.join(::Rails.root.to_s, 'public', 'temp', file_name)
  end

end

这种方法很丑陋,因为需要在服务器上保存一个临时文件。有没有不需要保存临时文件的方法呢?可以使用StringIO吗?


2
你知道使用文件系统是一种完全有效的做法,对吧?实际上,Unix 系统几乎完全基于文件系统,这就是为什么 /dev/null 存在的全部意义。我对这个解决方案更加关注的问题是它容易受到竞态条件的影响。 - Ken Li
我确信它是有效的,但创建一个文件意味着我需要一个cron作业来清理删除所有临时文件,如果这不发生可能会导致硬盘填满并使服务器崩溃。为什么要增加更多的烦恼呢?我非常有兴趣优雅地解决这个问题,而不需要一个临时文件。减少移动部件? - AnApprentice
@AnApprentice,使用Tempfile类可以通过垃圾回收器清理旧文件。请参见下面的答案。 - Mischa
1个回答

14

我之前的解决方案存在问题,因为临时文件已经关闭,所以无法再被Paperclip使用。下面的解决方案对我来说是有效的。我认为这是最干净的方式,并且(根据文档)确保在使用后删除临时文件。

将以下方法添加到您的 User 模型中:

def set_picture(data)
  temp_file = Tempfile.new(['temp', '.jpg'], :encoding => 'ascii-8bit')

  begin
    temp_file.write(data)
    self.picture = temp_file # assumes has_attached_file :picture
  ensure
    temp_file.close
    temp_file.unlink
  end
end

控制器:

current_user.set_picture(request.raw_post)
current_user.save

不要忘记在您的User模型文件顶部添加require 'tempfile'


1
然后你必须将Paperclip修改为按照你的意愿进行操作,或者使用一个不需要在文件系统上创建文件的不同文件处理库(例如Carrierwave)。无论如何,如果你担心需要清理旧文件,这个解决方案是有效的,因为垃圾回收器会替你完成。你对临时文件还有什么其他的顾虑吗? - Mischa
1
顺便说一下,普通的文件上传会以类似于这段代码的方式创建一个临时文件。 - Mischa
1
让我试着重现一下。仅从错误信息中无法得出任何线索。只是为了确保:你的“丑陋解决方案”可行吗?它生成了一个有效的jpeg图像,可以由Paperclip处理吗? - Mischa
1
问题在于临时文件已关闭,不能再与Paperclip一起使用。我更新了我的答案。上面的解决方案对我有效。 - Mischa
1
太棒了,非常优雅。谢谢你Mischa。 - AnApprentice
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接