ruby-on-rails - ActiveStorage如何防止重复文件上传;按文件名查找

标签 ruby-on-rails rails-activestorage

我正在解析电子邮件附件并将它们上传到 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_attachmentsactive_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/

相关文章:

ruby-on-rails - ActiveStorage::InvariableError in Home#index

ruby-on-rails - 事件存储 : get S3 key (not Rails blob key)

rails-activestorage - 如何处理 ActiveStorage 直接上传的 ActiveSupport::MessageVerifier::InvalidSignature 错误

ruby-on-rails - act_as_list 与 has_and_belongs_to_many 关系

ruby-on-rails - 登录用户和未登录用户的不同页面

mysql - 根据关联模型中的值对记录进行排序

ruby-on-rails - Rails Active Storage - 背景图像无效属性?

css - 如何风格化 Ruby on Rails 设计表单

ruby-on-rails - 由于 Sqlite3,部署 RoR 应用程序失败(已经尝试过其他帖子)

ruby-on-rails - 如何设置 ActiveStorage 以允许公共(public)和私有(private)附件