"path_for" вложения ActiveStorage на S3 - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть приложение, размещенное на Heroku, где один пользователь может ответить на тест и отправить несколько фотографий (через Active Storage, и файлы отправляются в корзину S3), а другой пользователь может видеть полученные ответы и фотографии.

Я использовал метод для загрузки пользователем всех фотографий викторины в ZIP-файл, но я продолжаю получать это сообщение об ошибке в реальном приложении:

NoMethodError (неопределенный метод`path_for 'для #ActiveStorage :: Service :: S3Service: 0x0000000006b47368>):

Для создания файла .zip используется метод:

def quiz_photos_download
  @quiz = Quiz.find(params[:quiz_id])
  @project = Project.find(@quiz.project_id)
  @photos = @quiz.room_photos

  arquivo = "#{Rails.root}/tmp/quiz_photos.zip"

  Zip::File.open(arquivo, Zip::File::CREATE) do |zipfile|
    @photos.each do |photo|
      zipfile.add(photo.filename, ActiveStorage::Blob.service.send(:path_for, photo.key))
    end
  end
      send_file(arquivo, :type => 'application/zip', :filename => "Fotos "+@project.name+".zip")
end

Я могу отобразить всеИзображения, отправленные пользователем в представлениях проектов, и массовая загрузка прекрасно работают, когда код запускается локально.

Есть идеи на этот счет?

1 Ответ

0 голосов
/ 13 декабря 2018

Вы используете бэкэнд S3 для хранения вложений Active Storage, чтобы файлы были отключены в каком-либо сегменте S3, а не где-либо в вашей файловой системе.Не существует пути для использования, как в случае с дисковой службой.

Вместо того, чтобы добавлять файлы в zip-файл по их путям, вам нужно будет загрузить изображения с S3 и добавить данные непосредственно в zip-файл.файл.Примерно так:

# The streaming API is a bit easier for this.
Zip::OutputStream.open(arquivo) do |zip|
  @photos.each do |photo|
    zip.put_next_entry(photo.filename)
    zip.print(photo.download)
  end
end

Вызов photo.download загрузит файл из S3 в строку в памяти.Это может поглотить больше памяти, чем вы хотели бы, поэтому вы можете использовать модуль ActiveStorage::Downloading для загрузки вложений во временные файлы, см. Обзорное руководство по активному хранилищу *1009* для получения дополнительной информации об использовании ActiveStorage::Downloading.

Этот процесс может быть медленным и ресурсоемким, поэтому вы можете перенести создание zip-файла в фоновую работу и затем уведомить человека о завершении работы.

...