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
Top comments (0)