after_create文件保存回调导致间歇性错误

时间:2015-12-06 18:01:49

标签: ruby-on-rails paperclip

在我的user模型中,我有一个after_create回调,如下所示:

def set_default_profile_image
  file = Tempfile.new([self.initials, ".jpg"])
  file.binmode
  file.write(Avatarly.generate_avatar(self.full_name, format: "jpg", size: 300))
  begin
    self.profile_image = File.open(file.path)
  ensure
    file.close
    file.unlink
  end
  self.save
end

self.initials只是一种返回用户首字母的实用工具方法,因此例如我的个人资料图片就是" HB.jpg"。)

如果我直接在现有用户上调用该方法,它可能有80%的时间可以工作。其他时候,它给我一个错误信息,这么长时间我无法在这里重现它(我甚至无法在tmux中向后滚动到足以看到它的开始)。错误消息(或者我可以看到它,无论如何)包含MIME类型列表,后跟此位:

content type discovered from file command: application/x-empty. See documentation to allow this combination.

如果我创建新用户,则回调会在100%的时间内产生相同的错误消息。

我的方法使用Avatarly gem生成占位符头像; gem以blob形式生成它们,因此创建了一个Tempfile来写入。

我无法理解为什么会出现上述错误。

3 个答案:

答案 0 :(得分:1)

确保full_name具有有效的返回值,并尝试将save电话移至begin部分。您可能正在竞争保存并且临时文件被删除/取消链接。

答案 1 :(得分:0)

当你这样做时,你会发生什么?

self.profile_image = File.open(file.path)

没有块,这与:

相同
self.profile_image = File.new(file.path)

它们都返回一个文件对象。是数据库中的profile_image?我非常确定您发送了一个要保留的File对象会很生气。如果您想要数据库中该文件的数据,请执行以下操作:

self.profile_image = File.open(file.path).read

如果要保存临时文件的路径:

self.profile_image = File.path(file.path)

如果您正在使用该路径,请记住您正在保存临时文件,并且该文件将不会持续很长时间!

答案 2 :(得分:0)

我在an issue on Paperclip's github找到了解决方案。我不太了解原因,但似乎这是一个文件系统问题,Tempfile在读入模型时尚未保存到磁盘。

解决方案是在分配之前对Tempfile做任何事情; file.read工作正常。

def set_default_profile_image
  file = Tempfile.new([self.initials, ".jpg"])
  file.binmode
  file.write(Avatarly.generate_avatar(self.full_name, format: "jpg", size: 300))
  file.read # <-- this fixes the issue
  begin
    self.profile_image = File.open(file.path)
  ensure
    file.close
    file.unlink
  end
  self.save
end