Today I Learned

This project exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day. Posts have a 200-word limit, and posting is open to any Rocketeer as well as selected friends of JetRockets. We hope you enjoy learning along with us.

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
Looking for help? Each developer at JetRockets has years of experience working with Ruby applications of all types and sizes. Contact us and find out how we can help you.