Today I Learned

A JetRockets project

1 post about #ruby

How to create zip files on the fly w/o Tempfile

There are many articles about how to archive files from the server and send a zip-file to a client without persisting it on the server. But usually they don’t literally do it, because they use temporary files.

There is a simple way to do it without creating any file though. You just have to put files directly to Zip::OutputStream and then read from it. Btw pay attention: you must rewind the stream before reading it.

# some files objects
def download(files)
  zip_stream = Zip::OutputStream.write_buffer do |zip|
    files.each.with_index(1) do |file, index|
     # file name must be uniq in archive
      zip.put_next_entry("#{file.name}--#{index}.#{file.extension}")
      zip.write(file.read.force_encoding('utf-8'))
    end
  end
  # important - rewind the steam
  zip_stream.rewind
  send_data zip_stream.read, 
            type: 'application/zip', 
            disposition: 'attachment', 
            filename: 'files-archive.zip'
end