🐈

CarrierWave で S3 からファイル取得して ZIP 形式で出力する手順

2022/02/14に公開

https://github.com/carrierwaveuploader/carrierwave

手順

  1. CarrierWave で S3 にアップロードしたファイルの URL を取得
  2. URI.open で TmpFile オブジェクトを取得
  3. zipline メソッドの引数に TmpFile オブジェクトを渡す

サンプルコード

# User.rb
mount_uploader :icon, IconUploader
# Method
url = user.icon.url
tmpfile = URI.open(url)
zipline([tmpfile], "/tmp/your_zip_filename.zip")

1. CarrierWave で S3 にアップロードしたファイルの URL を取得

例えば User がプロフィール画像を持っているとして、すでに S3 にアップロード済みの画像は以下のように URL が取得できる

url = user.icon.url
# => "https://your_hostname.s3.ap-northeast-1.amazonaws.com/uploads/path/to/your_filename.xlsx

最初にローカルホストで開発していたときには CarrierWave の url メソッドではなく path をコールして動作確認していたらうまく動かなかった。
ローカルホストでは CarrierWave の保存先の設定が config.storage = :file になっていたため動作したが、ステージング環境では path ではファイルの実体が取得できなかったため。

2. URI.open で Tmpfile オブジェクトを取得

tmpfile = URI.open(url)
# => #<Tempfile:/tmp/open-uri20220214-30801-19sw6bc>

1. で取得した URL の文字列を URI.open メソッドの引数に渡してやると、Tmpfile オブジェクトを返す。
これは File クラスへの Decorator で File オブジェクトと同じように扱うことができるらしい。

https://docs.ruby-lang.org/ja/latest/method/URI/s/open.html
https://docs.ruby-lang.org/ja/latest/class/Tempfile.html

3. zipline メソッドの引数に Tmpfile オブジェクトを渡す

zipline([tmpfile], "/tmp/your_zip_filename.zip")

Zipline gem を使って第一引数に複数のファイルオブジェクト、第二引数に出力する zip ファイル名を渡してやると zip ファイルがダウンロードできる。

https://github.com/fringd/zipline


それでは 👋

Discussion