ActiveStorage是否从S3服务上的附件对象下载文件/ IO?

时间:2019-01-24 20:02:19

标签: ruby-on-rails rails-activestorage

文件上传后,我要分析并立即处理。

我当前正在附加附件,然后分别处理:

current_account.archives.attach(archive_params)
current_account.archives.each do |archive|
  Job.enqueue(AccountArchiveImportJob.new(current_account.id, archive.id))
end

在工作中,我正在打开CSV并解析垃圾邮件

attachment = Account.find(account_id).archives.where(id: archive_id).first

CSV.parse(attachment.download) do |row|
  do_stuff_with_the_row(row)
end

我想做类似的事情:

CSV.foreach(attachment.open) do |row|
  do_stuff_with_the_row(row)
end

我找不到允许将附件转换回FILE的文档

4 个答案:

答案 0 :(得分:0)

您可以从附件中获取文件路径,然后打开文件。

path = ActiveStorage::Blob.service.send(:path_for, attachment.key)
File.open(path) do |file|
    #...
end

答案 1 :(得分:0)

Rails-6,我们将获得一个download方法,该方法将产生一个文件,但是您可以非常容易地获得它!

Add this downloader.rb file as an initializer

然后使用此模型

class Business < ApplicationRecord
  has_one_attached :csvfile
end

可以做到

ActiveStorage::Downloader.new(csvfile).download_blob_to_tempfile do |file|
  CSV.foreach(file.path, {headers: true}) do |row|
    do_something_with_each_row(row.to_h)
  end
end

编辑:不确定为什么花这么长时间才能找到service_url。方法更简单,但是noted that service_url should not be shown to users

open(csvfile.service_url)

答案 2 :(得分:0)

摘自Rails 5.2官方指南

class VirusScanner
  include ActiveStorage::Downloading

  attr_reader :blob

  def initialize(blob)
    @blob = blob
  end

  def scan
    download_blob_to_tempfile do |file|
      system 'scan_virus', file.path
    end
  end
end

所以你可以做

  include ActiveStorage::Downloading

  attr_reader :blob

  def initialize(blob)
    @blob = blob
  end

  def perform
    download_blob_to_tempfile do |file|
      CSV.foreach(file.path, {headers: true}) do |row|
        do_something_with_each_row(row.to_h)
      end
    end
  end

答案 3 :(得分:0)

至少从Rails 6.0 rc1起:

model.attachment_changes['attachment_name'].attachable

将为您提供原始TmpFile的IO,上传前