在Rails 5.2.1中,我为Disk
服务配置了ActiveStorage(5.2.1)。
我有一个Pic模型:
class Pic < ApplicationRecord
has_one_attached :image
end
我可以附加图像:
imgpath = "/tmp/images/..."
Pic.first.image.attach(io: File.open(imgpath), filename: imgpath)
我想通过Rake任务(但从Rails控制台完成的结果是一样的)执行此操作以批量上传图像,例如:
pfs = Dir['testpics/*']
Pic.all.each { |pic|
pf = pfs.shift
pic.image.attach(io: File.open(pf), filename: pf)
}
这运行没有错误。但是,令人惊讶的是(至少对我来说)安静一些(至少对我来说)图像之后没有相应的Blob,并且查询失败并显示500 Internal Server Error:Errno::ENOENT (No such file or directory @ rb_sysopen
。
检查pic.image.attached?
返回true。但是,pic.image.download
引发异常。
即使是陌生人,也可以在附加{em> 后立即呼叫pic.image.download
。 2秒后没有。
判断图像是否正确上传的唯一方法是在附加图像后等待约2秒钟,然后然后尝试下载。如果我在等待2秒钟后继续重试附件并检查是否正常,则所有图像都可以。但这显然不是正确的事情。 :)只是在附加调用之间等待是没有帮助的,我必须在等待后检查,然后重新附加,然后再次检查,直到确定为止-第一次尝试有时可以确定,有时第10次可以,但是最终将成功。
全部都在我的本地磁盘上,而不是Heroku中的临时存储。我也在Ubuntu 18.04(Bionic)上运行它,没有安装任何应删除斑点的东西(即没有杀毒软件或类似软件)。我真的认为问题出在ActiveStorage内部,或者是我使用它的方式。
这是怎么回事?几秒钟后已经成功上传了Blob,该怎么办?
使用S3服务,一切都很好,斑点不会消失。
答案 0 :(得分:2)
哇,我想我明白了。这不是ActiveStorage的主要问题,但是我将在此保留问题,以防其他人也有用。
事实证明,问题可能出在Dropbox上。 :)
使用Disk
策略会发生什么,ActiveStorage在storage/
目录中存储两个字符的标识符-与哈希类似。这些可能(而且经常会发生)只是大小写不同,例如存在一个zu
和一个Zu
目录。 Dropbox客户端对此进行干预的方式是,如果所有这些都位于与Dropbox同步的目录中,则这些目录将被重命名,例如,“ Zu
”将变为“ zu (Case Conflict)
”(因此Dropbox同步可跨平台使用)。
当然再也找不到这些blob,并且所有这些操作都是异步发生的,Dropbox客户端需要一些时间来重命名内容,这就是为什么它在附加图像后可以工作一段时间的原因。
因此吸取的教训是,ActiveStorage在Dropbox上无法正常工作。
答案 1 :(得分:0)
现在,ActiveStorage支持DropboxService。请关注activestorage-dropbox宝石
ActiveStorage :: Service :: DropboxService
将Dropbox存储服务包装为活动存储服务。
gem 'activestorage-dropbox'
用法
在config / storage.yml中声明一个Dropbox服务
dropbox:
service: Dropbox
access_token: ""
config.active_storage.service = :dropbox