Add a send_zip
method in your Rails controller to send a .zip
file containing one or many ActiveStorage objects.
Assuming you have an ActiveRecord model with ActiveStorage like this:
# app/models/user.rb
class User < ApplicationRecord
has_many_attached :pictures
end
You simply have to include ActiveStorage::SendZip
in your controller & use ActiveStorage::SendZip#send_zip
method. Just pass some ActiveStorage::Attached
objects as parameters:
# app/controllers/users_controller.rb
class UsersController < ApplicationController
include ActiveStorage::SendZip
# ...
# GET /users/1
# GET /users/1.zip
def show
respond_to do |format|
format.html { render }
format.zip { send_zip @user.pictures }
end
end
end
Will produce a .zip
archive like this:
├── a.jpg
├── b.png
└── c.gif
Ii will also prevent duplicate filename and add an SecureRandom.uuid
if two files as the same name.
You can also pass an Hash
parameter at send_zip
method to organize files in sublfolder:
# app/controllers/holidays_controller.rb
class HolidaysController < ApplicationController
include ActiveStorage::SendZip
def zip
send_zip {
'Holidays in Lyon <3' => Holidays.where(place: 'lyon').first.pictures,
'Holidays in Paris' => [
'Eiffle Tower' => Holidays.where(place: 'eiffle_tower').first.pictures,
Holidays.where(place: 'paris').first.pictures
]
}
end
end
Will produce a .zip
archive like this:
├── Holidays in Lyon <3
│ ├── a.jpg
│ ├── b.png
│ └── c.gif
└── Holidays in Paris
├── Eiffle Tower
├── d.jpg
├── e.jpg
├── f.jpg
├── a.jpg
├── b.png
└── c.gif
You can resize the images before zipping and downloading them :
# app/controllers/galleries_controller.rb
class GalleriesController < ApplicationController
include ActiveStorage::SendZip
# ...
# GET /galleries/1/download
def download
respond_to do |format|
if params[:format] == 'web_size'
format.zip { send_zip @gallery.photos, resize_to_limit: [1920, 1080] }
elsif params[:format] == 'tiny'
format.zip { send_zip @gallery.photos, resize_to_limit: [480, 270] }
else
format.zip { send_zip @gallery.photos }
end
end
end
end
Add this line to your application's Gemfile:
gem 'active_storage-send_zip'
And then execute:
$ bundle
Or install it yourself as:
$ gem install active_storage-send_zip
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/madeindjs/active_storage-send_zip. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
Everyone interacting in the ActiveStorage::SendZip project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.