ActiveStorage загрузить File / IO из объекта вложения на сервис S3? - PullRequest
0 голосов
/ 24 января 2019

После загрузки файла я хочу проанализировать и сразу обработать.

Я сейчас присоединяюсь, затем обрабатываю каждый:

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

Я не могу найти документацию, которая позволяет преобразовать вложение обратно в ФАЙЛ

Ответы [ 4 ]

0 голосов
/ 16 июля 2019

По крайней мере из Rails 6.0 rc1:

model.attachment_changes['attachment_name'].attachable

даст вам IO оригинального TmpFile ДО , который он загружен.

0 голосов
/ 29 января 2019

Rails-6 мы получим метод download, который даст файл, но вы можете получить это очень легко!

Добавить этот downloader.rb файл в качестве инициализатора

Тогда с учетом этой модели

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. Гораздо проще, но отметил, что service_url не должен показываться пользователям

open(csvfile.service_url)
0 голосов
/ 20 февраля 2019

Из 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
0 голосов
/ 26 января 2019

Вы можете получить путь к файлу из вложения, а затем открыть файл.

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