I am attempting to use rubyzip to create zip archives on the fly in my app. I'm using their readme as a starting point. I added the gem to my Gemfile:
gem 'rubyzip'
Then ran bundle install and restarted the rails server.
My controller code is:
require 'rubygems'
require 'zip'
filename = "#{Time.now.strftime('%y%m%d%H%M%S')}"
input_filenames = ["#{filename}.txt"]
zip_filename = "#{filename}.zip"
Zip::File.open(zip_filename, Zip::File::CREATE) do |zipfile|
input_filenames.each do |f|
zipfile.add(f, directory + '/' + f)
end
end
The error I'm getting is: cannot load such file -- zip
I've tried require 'zip/zip' but it produces the same error.
Thanks in advance!
You might be looking at an example that's too new.
If you are using Rubyzip 0.9.x, then you need to follow this example:
(require "zip/zip", then use Zip::ZipFile instead of Zip::File)
require 'zip/zip'
folder = "Users/me/Desktop/stuff_to_zip"
input_filenames = ['image.jpg', 'description.txt', 'stats.csv']
zipfile_name = "/Users/me/Desktop/archive.zip"
Zip::ZipFile.open(zipfile_name, Zip::ZipFile::CREATE) do |zipfile|
input_filenames.each do |filename|
# Two arguments:
# - The name of the file as it will appear in the archive
# - The original file, including the path to find it
zipfile.add(filename, folder + '/' + filename)
end
end
I suggest you to use:
gem 'rubyzip', "~> 1.1", require: 'zip'
and then require 'zip' in your controller should work fine.
Interface of rubyzip was changed. You using old version. Docs on rubydoc.info from master branch.
Related
I am implementing feature which allows user to either download single file or multiple files from S3.
Single file downloading is working properly, but for multiple files I am receiving error on Heroku,
Errno::ENOENT (No such file or directory # rb_file_s_lstat )
Controller code snippet for downloading files as zip format is as below,
def method_name
zipfile_name = "#{Rails.root}/public/archive.zip"
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile |
#transfer.transfer_attachments.each do |attachment |
zipfile.add(attachment.avatar.file.filename, attachment.avatar.url)
end
end
send_file(File.join("#{Rails.root}/public/", 'archive.zip'), : type =>
'application/zip', : filename => "#{Time.now.to_date}.zip")
end
Gemfile
ruby '2.3.1'
gem 'rails', '~> 5.0.1'
gem 'rubyzip', '>= 1.0.0'
gem 'zip-zip'
This zipfile functionality works proper with locally stored files.
I would like to answer to my question.
Steps are as follow,
Downlaod files from S3 and store them locally
Add them to zip by first creating zip and then add files to it.
Download zip archive
Here is controller code,
require 'open-uri'
def download_all_files
folder_path = "#{Rails.root}/public/downloads/"
zipfile_name = "#{Rails.root}/public/archive.zip"
FileUtils.remove_dir(folder_path) if Dir.exist?(folder_path)
FileUtils.remove_entry(zipfile_name) if File.exist?(zipfile_name)
Dir.mkdir("#{Rails.root}/public/downloads")
#model_object.each do |attachment|
open(folder_path + "#{attachment.avatar.file.filename}", 'wb') do |file|
file << open("#{attachment.avatar.url}").read
end
end
input_filenames = Dir.entries(folder_path).select {|f| !File.directory? f}
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
input_filenames.each do |attachment|
zipfile.add(attachment,File.join(folder_path,attachment))
end
end
send_file(File.join("#{Rails.root}/public/", 'archive.zip'), :type => 'application/zip', :filename => "#{Time.now.to_date}.zip")
end
Guess: You are adding attachments as urls, but you should be adding (local) file paths instead.
I am trying to unzip a file in my Spree plugin.
Defined the unzipping method in a module which looks like this.
module ImportImages
class Zipper
def self.unzip(zip, unzip_dir, remove_after = false)
Zip::File.open(zip) do |zip_file|
zip_file.each do |f|
f_path=File.join(unzip_dir, f.name)
FileUtils.mkdir_p(File.dirname(f_path))
zip_file.extract(f, f_path) unless File.exist?(f_path)
end
end
FileUtils.rm(zip) if remove_after
end
end
end
I have included the rubyzip gem in my Gemfile.
gem 'rubyzip'
gem 'zip-zip'
When trying to run it, I am getting the following error.
NameError - uninitialized constant ImportImages::Zipper::Zip:
I have tried every solution provided in stackoverflow and other sites. I tried downgrading the version of rubyzip which is 1.2.0 now and add require 'zip' or require 'zip/zip'. Both returned load error.
I have try adding require 'zip/filesystem' to the class. But got
LoadError - cannot load such file -- zip/zipfilesystem
Any solution for this?
Include rubyzip in gem file in this way:
gem 'rubyzip', require: 'zip'
See this question
It's looking for a nested Constant. Change line Zip::File.open(zip) do |zip_file| with below:
::Zip::File.open(zip) do |zip_file|
It should work.
Also make sure you require rubygem/bundle setup. Though in spree it should've already been done.
Babar's answer is correct, but you also need to add require 'zip' in application_controller.rb
I have some common code that I want to share between couple of my rails app.
I've generated my gem like so :
bundle gem document-common
My gemspec looks like so :
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'document_common/version'
Gem::Specification.new do |spec|
spec.name = "document_common"
spec.version = DocumentCommon::VERSION
spec.authors = ['Author']
spec.email = ['test#domain.com']
spec.summary = 'Common Models and Lib'
spec.description = 'Common Models and Lib'
spec.homepage = 'google.com'
spec.license = 'WTFPL'
spec.files = Dir["{app,config,db,lib}/**/*", "LICENSE", "Rakefile", "README.rdoc"]
spec.test_files = Dir["spec/**/*"]
spec.test_files.reject! { |file| file.match(/[.log|.sqlite3]$/) }
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.11"
spec.add_development_dependency "rake", "~> 10.0"
end
In my lib folder I have this :
document_common
document_common.rb
Folder document_common and ruby file document_common.rb, and the ruby file has this content :
require 'document_common/version'
module DocumentCommon
# Your code goes here...
end
Then inside document_common there is a version.rb with this content :
module DocumentCommon
VERSION = '0.1.0'
end
And document.rb with this content:
module DocumentCommon
class Document < ActiveRecord::Base
end
end
So I push this gem to my git repo. And then I add this gem info to my Gemfile in the rails 4 app do a bundle install, but when I refer to DocumentCommon::Document I get this error :
NameError: uninitialized constant DocumentCommon::Document
However if I retrieve the info about the version DocumentCommon::VERSION I get no errors and get the actual version. Also when I do DocumentCommon.constants I get [:VERSION]. What am I doing wrong here? What do I need to do to have access in my main rails app to DocumentCommon::Document model?
You can use the autoload, check out the devise gem does exactly that:
https://github.com/plataformatec/devise/blob/master/lib/devise.rb
I'm building a gem simply to go through the processes, and I'm trying to add a generator to it. When I run $ rails g, my generator shows up:
Mygem:
mygem:install
but rails doesn't recognize it
rails g mygem:install
Could not find generator mygem:install.
I have my gem pointed to the latest version in my gemfile
#mygem/lib/rails/generators/mygem_generator.rb
require 'rails/generators'
require 'rails/generators/base'
module Mygem
class InstallGenerator < Rails::Generators::Base
def test
puts 'hi'
end
end
end
.
-mygem
- lib
- generators
- mygem
mygem_generator.rb
- mygem
version.rb
mygem.rb
- pkg
mygem-0.0.1.gem
.gitignore
Gemfile
LICENSE.txt
README.md
Rakefile
mygem.gemspec
.
#mygem.gemspec
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'mygem/version'
Gem::Specification.new do |spec|
spec.name = "mygem"
spec.version = Mygem::VERSION
spec.authors = ["me"]
spec.email = ["email#email.com"]
spec.summary = %q{lalaala}
spec.description = %q{lalalalal}
spec.homepage = ""
spec.license = "MIT"
spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.5"
spec.add_development_dependency "rake"
end
We've just made a gem, and have a generator which allows you to call rails generate exception_handler:install, like this:
#lib/generators/my_gem/install_generator.rb
module MyGem
class InstallGenerator < Rails::Generators::Base
def test
puts "hi"
end
end
end
This should help you - it works for us
I faced this issue after publishing my first public gem, it's because the bundler, or let's say the Rails app don't have access to the actual repository with the generator (I believe so).
I kept including gem 'spree_custom_checkout'
no luck to see the gem's generator when typing rails g.
Then I did this:
gem 'spree_custom_checkout', github: '0bserver07/Spree-Custom-Checkout'
and bam the generator shows up!
steps:
I did `gem build spree_custom_checkout.gemspec.
add it to the github repo, and push to the repostiory.
link to the repository.
This question already has answers here:
Rails 3 generators in gem
(2 answers)
Closed 8 years ago.
I am fairly new to Ruby/Rails framework. I have a simple generator in my Rails application at lib/generators. The generator's function is to copy one of the files in the templates/myfile.yml directory into config/myfile.yml.
Now I would like to use this generator in another app. So, I would like to package this as a gem. I have generated gem using bundler and it contains the following file structure:
lib/
mygem/
version.rb
generators/
mygem/
install/
templates/
somefile.yml
install_generator.rb
USAGE
mygem.rb
mygem.gemspec
Gemfile
Gemfile.lock
LICENSE.txt
Rakefile
README.md
Content of install_generator is as follows:
require 'rails/generators'
module Mygem
module Generators
class InstallGenerator < Rails::Generators::Base
source_root File.expand_path('../templates', __FILE__)
def generate_something
copy_file "something.yml", "#{Rails.root}/config/something.yml"
end
end
end
end
Following is the content of mygem.gemspec:
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'mygem/version'
Gem::Specification.new do |spec|
spec.name = "mygem"
spec.version = MyGem::VERSION
spec.authors = ["Swaroop SM"]
spec.email = ["myemail#gmail.com"]
spec.description = %q{Something}
spec.summary = %q{Something}
spec.homepage = ""
spec.license = "MIT"
spec.files = `git ls-files`.split($/)
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rake"
end
I reckon there is something missing in my lib/mygem.rb
require "mygem/version"
module Mygem
# Your code goes here...
end
I have no problem in building and pushing it to rubygems.org.
Inorder to use this in one of my rails app's, I added this to the Gemfile and run bundle install. The problem is now when I run rails g mygem:install it throws an error that says:
Could not find generator mygem:install.
What am I doing wrong?
I solved the issue. I had forgotten to add rails as a dependency in my gemspec file. i.e., I had to include the following in mygem.gemspec:
spec.add_development_dependency "rails", "~> RAILS_VERSION"