Question

I am attempting to use the roo gem to process .xlsx spreadsheets that are uploaded by an outside party. I'm getting the following error:

LoadError (cannot load such file -- zip/zipfilesystem):

I've found a lot of questions similar to this one (such as cannot load such file -- zip/zip) and I've tried to follow their solutions. So far, to no avail.

I originally required 'roo' in the controller, and after getting this error tried requiring 'zip/zip', 'zip/zipfilesystem', and just 'zip'. None of these seem to fix anything. I've also tried adding :require => 'zip', :require => 'zip/zipfilesystem', :require => 'zip/zip' to the Gemfile, and none of that seemed to change anything. Here is some pertinent code:

in Gemfile:

# for spreadsheet upload management
gem 'roo'
gem 'rubyzip'
gem 'spreadsheet'
gem 'nokogiri'

installed versions:

nokogiri (1.6.0)
roo (1.12.1)
rubyzip (1.0.0)
spreadsheet (0.8.9)

in Controller:

require 'roo'

module BatchOrderProcessing
  class DataFilesController < ApplicationController

    def create
      # some code here ...

      when ".xlsx"
        spreadsheet = Roo::Excelx.new(uploaded_io.path, nil, :ignore)
        header = spreadsheet.row(1)
        if # some validation stuff...
          puts "spreadsheet format inappropriate"
          redirect_to # some place
        end
        process_datafile(fname, spreadsheet)
        # more code ...
    end

private

  def process_datafile(fname, spreadsheet)
    @df = DataFile.new
    @df[:filename] = ActiveRecord::Base.connection.quote(fname)

    if @df.save
      begin
        # parse asynchronously
        datafile_scheduler = Rufus::Scheduler.new

        datafile_scheduler.in '3s' do
          @df.process_spreadsheet(spreadsheet)
        end
        redirect_to @df
      rescue => e
        # more code ...
      end
    else
       # more code ...
    end
  end

I think this thing is crapping out before it gets to the model (where the process_spreadsheet() code is), but just in case, here's some model code:

def process_spreadsheet(spreadsheet)
    # do some stuff
    puts "parsing spreadsheet"
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      row_array << row
      invoice << row.to_s

  # some more code....

    dfi = DataFileItem.new()
    dfi.attributes = row.to_hash.slice(*accessible_attributes)
    dfi.data_file_id = self.id
    dfi.save
    self.data_file_items << dfi

  #  Update stuff in our DB based on rows in row_array...

end

I'm using rails 3.2.13 and ruby 2.0.0p195.

Am I requiring the wrong thing (or in the wrong way) somewhere? Let me know if any other code snippets would be helpful. Thaaaaanks.

Was it helpful?

Solution

rubyzip v1.0.0 was released 29 August 2013: https://github.com/rubyzip/rubyzip/releases

This is a new major version number, and more than one gem or project that depends on this has been caught out by the break with backwards-compatibility.

The quickest "get my code working like before" fix is to alter Gemfile reference to rubyzip:

gem 'rubyzip', '< 1.0.0'

In the longer-term, this may not be the best fix, it depends on how and/or why you are using rubyzip. I expect some gem publishers such as roo's authors will need to figure out how to transition nicely so that their own users don't end up with simultaneous requirements for incompatible versions of rubyzip.


Just opinion:

Seeing this in action has actually made me much less a fan of Ruby gems semantic versioning for major versions. If I ever break with backwards compatibility on any of my own projects, I think I'll just start a new gem, and put a notice on the old gem.

OTHER TIPS

Try adding the zip-zip gem to your project. It provides a simple adapter for your dependencies using the RubyZip v0.9.9 interface allowing you to upgrade to RubyZip v1.0.0.

This has been fixed in the roo gem. You need to update to version 1.12.2 or higher to fix. See the issue here: https://github.com/Empact/roo/pull/65

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top