How to unzip a file in Ruby on Rails?

siamii picture siamii · Feb 9, 2012 · Viewed 36.5k times · Source

I'm uploading a file to the server in Ruby on Rails

Normally, it's a text file and I save it in the model as a 'file' field in a Submission ActiveRecord with other fields such as title of submission.. etc.

However, the user can also submit a zip file. In this case the zipfile should unzipped and for each file in the zip a new Submission should be created with the same text fields, but current file.

How can I accomplish this?

I looked at unzip examples on the net, but most use a directory to unzip the files to. I'm not sure if I need that as in the current create method of SubmissionsController, a file object is received and I presume the path to save the file to is automatically generated when the Submission save method is called. So I was thinking that maybe I should unzip the zipfile in memory to get an array of file objects and then create a new Submission with each file object but same fields and then let ActiveRecord generate the file paths for each one when it saves them to the database. I might be wrong here, because I'm kind of new to Rails and Ruby.

Answer

Ben Lee picture Ben Lee · Feb 9, 2012

I'd use the rubyzip gem. Specifically this part: https://github.com/rubyzip/rubyzip/blob/master/lib/zip/filesystem.rb

It creates an artificial file system in memory mirroring the contents of the zip file. Here's an example based of the example from the docs:

Rubyzip interface changed!!! No need to do require "zip/zip" and Zip prefix in class names removed.

require 'zip'

Zip::File.open("my.zip") do |zipfile|
  zipfile.each do |file|
    # do something with file
  end
end

In your case, just put the name of the uploaded tempfile where my.zip is in the example, and you can loop through the contents and do your regular operations on them.