How to unzip a file in Ruby on Rails?

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.


From the RubyZip project page:

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

So, the example code from @ben-lee should be updated to something like this:

require 'zip'

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

Extract Zip files in Ruby

Once you've installed the rubyzip gem, you can use this method to extract zip files:

require 'zip'

def extract_zip(file, destination)
  FileUtils.mkdir_p(destination)

  Zip::File.open(file) do |zip_file|
    zip_file.each do |f|
      fpath = File.join(destination, f.name)
      zip_file.extract(f, fpath) unless File.exist?(fpath)
    end
  end
end

You use it like this:

extract_zip(zip_path, extract_destination)

Worked for me:

gem install rubyzip

main.rb

require 'zip'

def extract_zip(file, destination)
  FileUtils.mkdir_p(destination)

  Zip::File.open(file) do |zip_file|
    zip_file.each do |f|
      fpath = File.join(destination, f.name)
      FileUtils.mkdir_p(File.dirname(fpath))
      zip_file.extract(f, fpath) unless File.exist?(fpath)
    end
  end
end

extract_zip('file.zip', 'tmp')