Zip up all Paperclip attachments stored on S3

前端 未结 2 1419
别那么骄傲
别那么骄傲 2021-02-07 11:39

Paperclip is a great upload plugin for Rails. Storing uploads on the local filesystem or Amazon S3 seems to work well. I\'d just assume store files on the localhost, but the use

相关标签:
2条回答
  • 2021-02-07 11:52

    You almost certainly want to use e.abstract.to_file.path instead of e.abstract.url(...).

    See:

    • Paperclip::Storage::S3::to_file (should return a TempFile)
    • TempFile::path

    UPDATE

    From the changelog:

    New in 3.0.1:

    • API CHANGE: #to_file has been removed. Use the #copy_to_local_file method instead.
    0 讨论(0)
  • 2021-02-07 12:12

    @vlard's solution is ok. However I've run into some issues with the to_file. It creates a tempfile and the garbage collector deletes (sometimes) the file before it was added to the zip file. Therefor, I'm getting random Errno::ENOENT: No such file or directory errors.

    So I'm using the following code now (I've kept the initial code variables names for consistency with the initial question)

    format.zip {
                registrations_with_attachments = Registration.find_by_sql('SELECT * FROM registrations WHERE abstract_file_name NOT LIKE ""')
                headers['Cache-Control'] = 'no-cache'  
    
                #please note that using nanoseconds option in strftime reduces the risks concerning the situation where 2 or more  users initiate the download in the same time
                tmp_filename = "#{RAILS_ROOT}/tmp/tmp_zip_" <<
                                Time.now.strftime('%Y-%m-%d-%H%M%S-%N').to_s <<   
                                ".zip"
    
                # rubyzip gem version 0.9.4                
                zip = Zip::ZipFile.open(tmp_filename, Zip::ZipFile::CREATE) 
                zip.close
    
                registrations_with_attachments.each { |e|
                     file_to_add = e.file.to_file
                     zip = Zip::ZipFile.open(tmp_filename)
                     zip.add("abstracts/#{e.abstract.original_filename}", file_to_add.path)
                     zip.close
                     puts "added #{file_to_add.path} to #{tmp_filename}"  #force garbage collector to keep the file_to_add until after the file has been added to zip
                }
    
                send_data(File.open(tmp_filename, "rb+").read, :type => 'application/zip', :disposition => 'attachment', :filename => tmp_filename.to_s)
                File.delete tmp_filename
          }
    
    0 讨论(0)
提交回复
热议问题