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.
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 torubyzip
: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 asroo
'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 ofrubyzip
.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.