2013-09-06 14 views
8

Próbuję użyć klejnotu roo do przetwarzania arkuszy kalkulacyjnych .xlsx, które są przesyłane przez stronę zewnętrzną. Dostaję następujący błąd:Ruby on Rails Klejnot roo nie może załadować pliku zip/zipfilesystem

LoadError (nie może wczytać takiego pliku - Zip/zipfilesystem):

Znalazłem wiele pytań podobne do tego (jak nie można załadować taki plik - zip/zip) i starałem się podążać za ich rozwiązaniami. Jak dotąd, bezskutecznie.

Pierwotnie wymagane "roo" w kontroler, a po otrzymaniu tego błędu próbowałem wymagające "zip/zip", "zip/zipfilesystem" i po prostu "zip". Żadne z nich nie wydaje się niczego naprawiać. Próbowałem też dodać: require => 'zip',: require => 'zip/zipfilesystem',: require => 'zip/zip' do Gemfile'a i nic z tego nie zmieniło niczego. Oto stosowny kod:

w Gemfile:

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

zainstalowane wersje:

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

kontroler:

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 

Myślę, że ta sprawa jest crapping przed robi do modelu (gdzie jest kod process_spreadsheet()), ale na wszelki wypadek oto kod modelu:

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 

Używam szyn 3.2.13 i ruby ​​2.0.0p195.

Czy potrzebuję czegoś niewłaściwego (lub w niewłaściwy sposób) gdzieś? Daj mi znać, jeśli pomocne będą inne fragmenty kodu. Thaaaaanks.

+0

Czy próbowałeś: 'gem 'rubyzip', '<1.0.0'' w twoim' Gemfile'? Zobacz readme na https://github.com/rubyzip/rubyzip –

+0

Nie ... nie, nie mam. I to jest rażąco na mojej twarzy. Wygląda na to, że naprawiłam mój problem. Pojawił się kolejny problem, ale wydaje się niezwiązany. Jeśli rzucisz to jako odpowiedź, z przyjemnością to zaakceptuję. – Deranger

Odpowiedz

13

rubyzip v1.0.0 został wydany 29 sierpnia 2013: https://github.com/rubyzip/rubyzip/releases

To nowy główny numer wersji, a więcej niż jeden gem lub projekt, który polega na tym został złapany przez zerwanie z wstecznej kompatybilności.

Najszybszy „dostać mój kod działa jak przedtem” fix jest zmiana Gemfile odniesienie do rubyzip:

gem 'rubyzip', '< 1.0.0' 

W dłuższej perspektywie, to może nie być najlepszym fix, to zależy od tego w jaki sposób i/lub dlaczego używasz rubyzip. Oczekuję, że niektórzy wydawcy klejnotów, tacy jak autorzy roo, będą musieli wymyślić, jak ładnie przejść, aby ich użytkownicy nie musieli skończyć z jednoczesnymi wymaganiami dla niekompatybilnych wersji rubyzip.


Wystarczy opinia:

Widząc to w akcji rzeczywiście sprawiło, że znacznie mniej fanem Ruby klejnotów semantycznej wersjonowanie dla głównych wersjach. Jeśli kiedykolwiek złamie się kompatybilność wsteczną w którymkolwiek z moich własnych projektów, myślę, że po prostu zacznę nowy klejnot i umieszczę informację o starym klejnocie.

+0

Bardzo ładne wyjaśnienie. Wielkie dzięki. – Deranger

11

Spróbuj dodać klejnot zip-zip do swojego projektu. Zapewnia prosty adapter dla twoich zależności przy użyciu interfejsu RubyZip v0.9.9 umożliwiającego uaktualnienie do RubyZip v1.0.0.

+0

OMG. Nigdy nie spodziewałem się, że to zadziała! ale powiedziałem, hej, spróbuję i zadziałało! Wielkie dzięki Orien! – Aleks