我正在解析电子邮件附件并将它们上传到 S3 中的 ActiveStorage。
我们希望它忽略重复项,但我看不到通过这些属性进行查询。
class Task < ApplicationRecord
has_many_attached :documents
end
然后在我的电子邮件 webhook 作业中
attachments.each do |attachment|
tempfile = open(attachment[:url], http_basic_authentication: ["api", ENV.fetch("MAILGUN_API_KEY")])
# i'd like to do something like this
next if task.documents.where(filename: tempfile.filename, bytesize: temfile.bytesize).exist?
# this is what i'm currently doing
task.documents.attach(
io: tempfile,
filename: attachment[:name],
content_type: attachment[:content_type]
)
end
不幸的是,如果有人转发相同的文件,我们就会重复,而且往往更多。
使用当前解决方案编辑:
tempfile = open(attachment[:url], http_basic_authentication: ["api", ENV.fetch("MAILGUN_API_KEY")])
md5_digest = Digest::MD5.file(tempfile).base64digest
# if this digest already exists as attached to the file then we're all good.
next if ActiveStorage::Blob.joins(:attachments).where({
checksum: md5_digest,
active_storage_attachments: {name: 'documents', record_type: 'Task', record_id: task.id
}).exists?
最佳答案
Rails 使用 2 个表来存储附件数据; active_storage_attachments
和 active_storage_blobs
active_storage_blobs
表包含上传文件的校验和。
您可以轻松加入此表以验证文件是否存在。
根据@gustavo 的回答,我得出以下结论:
attachments.each do |attachment|
tempfile = TempFile.new
tempfile.write open(attachment[:url], http_basic_authentication: ["api", ENV.fetch("MAILGUN_API_KEY")])
checksum = Digest::MD5.file(tempfile.path).base64digest
if task.documents.joins(:documents_blobs).exists?(active_storage_blobs: {checksum: checksum})
tempfile.unlink
next
end
#... Your attachment saving code here
end
注意:记得在你使用它的类中要求'tempfile'
关于ruby-on-rails - ActiveStorage如何防止重复文件上传;按文件名查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54190118/