NameError (uninitialized constant Unzipper::Zip) but only on Heroku deploy (Rails)
Asked Answered
T

1

7

I have a class unzipper.rb that unzips a file using Rubyzip.

In my local environment, I can succesfully unzip a file without explictly including the dependency using require 'zip'

On Heroku though, I get an NameError (uninitialized constant Unzipper::Zip) which I could only resolve by using the explict require

Question: Why would this be necessary in the Heroku environment, but not on localhost? I was under the impression that Rails required all gems automatically.

app/services/unzipper.rb

require 'zip'  # Only required for Heroku. Works locally without!

class Unzipper

  OVERRIDE_FILES = true

  def initialize(file)
    @file = file
  end

  def self.unzip(file, &block)
    Unzipper.new(file).unzip(&block)
  end

  def unzip
    open_zip do |zip|
      yield extract_files(zip)
    end
  end

  private

  def open_zip(&block)
    ::Zip::File.open(@file.path, &block)
  end

  def extract_files(zip)
    files = []
    zip.each do |entry|
      path = "#{rails_temp_directory}/#{entry.name}"
      entry.extract(path) { OVERRIDE_FILES }
      files << path
    end
    files
  end

  def rails_temp_directory
    "#{Rails.root}/tmp"
  end
end

Heroku output when running bundler includes:

remote:        Using rubyzip 1.1.7

I verified both are using the same version of Ruby.

There is no initializer or environment config for Rubyzip.

Gemfile

source 'https://rubygems.org'

gem 'rails', '4.2.0'

gem 'pg', group: :production

gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc

gem 'slim-rails'

gem 'paperclip'
gem 'rest-client'

gem 'bootstrap-sass', '~> 3.3.3'

gem 'validates_serialized'

gem 'puma'

gem "nokogiri"
gem "cocoon"
gem 'sidekiq'
gem 'sinatra', :require => nil # For sidekiq web monitoring
gem 'aws-sdk', '< 2.0'
gem 'rails_12factor', group: :production
gem 'rubyzip'

group :development, :test do
  gem 'byebug'

  gem 'web-console', '~> 2.0'

  gem 'spring'

  gem 'sqlite3'

  gem 'shoulda-matchers'
  gem 'rspec-rails'
  gem 'factory_girl_rails'
  gem 'capybara'
  gem 'selenium-webdriver'
  gem 'database_cleaner'
  gem 'guard-rspec'
  gem 'faker'
end

group :test do 
  gem 'webmock'
end

ruby '2.2.0'
Transmitter answered 22/9, 2015 at 15:11 Comment(6)
Probably an environment issue. Try setting your local RAILS_ENV to production to see if the same problem happens.Pancreas
Do you run your script via bundle exec?Lhasa
@brito I'm away from my office but will try that!Transmitter
@Alexey this is called from a rails controller and I assume heroku runs rails with bundle exec?Transmitter
Can you share a stacktrace of the error? The big difference between production and dev environments is that files are being eagerly loaded in production by default. rubyzip's main file name is different than its gem name, so you might have to specify it explicitly in the Gemfile: gem 'rubyzip', require: 'zip'Regressive
@Regressive that fixed it and I learned something new :) Thanks! If you post your answer I'll accept it.Transmitter
R
14

Rubyzip's main file name is different than its gem name, so you might have to specify it explicitly in the Gemfile:

gem 'rubyzip', require: 'zip'
Regressive answered 23/9, 2015 at 13:17 Comment(1)
Nice! This worked for me. I feel like I would have never figured that out. High five @fivedigit!Flagg

© 2022 - 2024 — McMap. All rights reserved.