after_create 文件保存回调导致间歇性错误
after_create file saving callback resulting in intermittent error
在我的 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
只是一个 returns 用户首字母的实用方法,因此例如我的个人资料图片将是 "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
来写入。
我不明白为什么会出现上面的错误。
确保 full_name
具有有效的 return 值并尝试将您的 save
调用移至 begin
部分。您可能正在与保存赛跑并且临时文件为 removed/unlink.
当你这样做时,你期望发生什么?
self.profile_image = File.open(file.path)
没有块,这等同于:
self.profile_image = File.new(file.path)
它们都是return一个文件对象。 profile_image 在数据库中吗?我很确定您发送要持久保存的 File 对象会很生气。如果您想要数据库中该文件的数据,请执行以下操作:
self.profile_image = File.open(file.path).read
如果要保存临时文件的路径:
self.profile_image = File.path(file.path)
如果您正在使用该路径,请记住您正在保存一个临时文件,该文件不会保存很长时间!
我在 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
在我的 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
只是一个 returns 用户首字母的实用方法,因此例如我的个人资料图片将是 "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
来写入。
我不明白为什么会出现上面的错误。
确保 full_name
具有有效的 return 值并尝试将您的 save
调用移至 begin
部分。您可能正在与保存赛跑并且临时文件为 removed/unlink.
当你这样做时,你期望发生什么?
self.profile_image = File.open(file.path)
没有块,这等同于:
self.profile_image = File.new(file.path)
它们都是return一个文件对象。 profile_image 在数据库中吗?我很确定您发送要持久保存的 File 对象会很生气。如果您想要数据库中该文件的数据,请执行以下操作:
self.profile_image = File.open(file.path).read
如果要保存临时文件的路径:
self.profile_image = File.path(file.path)
如果您正在使用该路径,请记住您正在保存一个临时文件,该文件不会保存很长时间!
我在 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