Last Updated: February 25, 2016
·
1.309K
· Alexandr K

Upload zipentries using paperclip

Lets say someone on your website is going to upload zip packages and you need to read this package using any rules and then save it to the cloud it should be easy to do using Asset model and special adapter for paperclip.

In your worker or before filter you can do something like this for reading package.

Zip::ZipFile.foreach(file).map do |entry|
  if entry.file?
    model_container.assets.create(item: entry) # or build
  end
end

Place this file under lib folder and require for the model that's going to use adapter(for me it's a asset model).

require 'weakref'

module Paperclip
  class ZipEntryAdapter < StringioAdapter
    def initialize(target)
      target.instance_eval do
        def original_filename
          to_s
        end
      end

      super(target)
    end

    def copy_to_tempfile(src)
      content = WeakRef.new(src.get_input_stream.read)
      destination.write(content)
      destination.rewind

      # cleanup memory that we spent for reading zip entry.
      GC.start

      destination
    end
  end
end

Paperclip.io_adapters.register Paperclip::ZipEntryAdapter do |target|
  Zip::ZipEntry === target
end