简体   繁体   English

S3上的“ path_for” ActiveStorage附件

[英]“path_for” ActiveStorage attachments on S3

I have an application hosted on Heroku, where one user can answer a quiz and submit some photos (via Active Storage, and the files are sent to a S3 bucket), and another user can see the retrieve the answers and photos. 我在Heroku上托管了一个应用程序,其中一个用户可以回答测验并提交一些照片(通过Active Storage,并将文件发送到S3存储桶),而另一个用户可以看到检索的答案和照片。

I used a method for the user download all photos of a quiz on a .zip file, but I keep getting this error message on the live application: 我使用了一种方法来让用户将测验的所有照片下载到.zip文件中,但是我一直在实时应用程序上收到此错误消息:

NoMethodError (undefined method `path_for' for #ActiveStorage::Service::S3Service:0x0000000006b47368>): NoMethodError(#ActiveStorage :: Service :: S3Service:0x0000000006b47368>的未定义方法`path_for'):

The method used to create the .zip file is: 用于创建.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

I can display all the images sent by the user on the projects views, and the bulk download works just fine when the code is run locally. 我可以在项目视图上显示用户发送的所有图像,并且在本地运行代码时,批量下载工作正常。

Any ideas on this? 有什么想法吗?

You're using the S3 backend to store your Active Storage attachments so the files are off in some S3 bucket rather than anywhere in your file system. 您正在使用S3后端存储Active Storage附件,因此文件不在某个S3存储桶中,而不是在文件系统中的任何位置。 There is no path to use like there is with the disk service. 没有像磁盘服务一样可以使用的路径。

Instead of adding files to the zip file by their paths, you'll have to download the images from S3 and add the data directly to the zip file. 您不必从文件的路径将文件添加到zip文件中,而必须从S3下载图像并将数据直接添加到zip文件中。 Something like this: 像这样:

# 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

The photo.download call will download the file from S3 into an in-memory string. photo.download调用会将文件从S3下载到内存中的字符串中。 This can chew up more memory than you'd like so you might want to use the ActiveStorage::Downloading module to help download the attachments to temp files, see the Active Storage Overview Guide for some information on using ActiveStorage::Downloading . 这样可能会消耗更多的内存,因此您可能想使用ActiveStorage::Downloading模块来帮助将附件下载到临时文件,请参阅《 Active Storage概述指南》以获取有关使用ActiveStorage::Downloading一些信息。

This process could get slow and resource intensive so you might want to push the zip creation off to background job and then notify the person when the job is finished. 此过程可能会变慢并且占用大量资源,因此您可能需要将zip创建推迟到后台作业,然后在作业完成时通知此人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM