【Rails】postしたzipを展開して処理をする方法
[:contents] Ruby on Railsでフロント側からzipファイルを送信して、サーバー側で展開して保存するというような処理を行いたかったのですが、結構ハマったり悩んでしまったので、書き残します。 ※今回はzipファイルの中に画像が入っている想定です。
zipをPostするまで
View側でPostできるようにする
= form_tag(create_item_by_zip_path(@hoge), multipart: true) do input type='file' name='zip_file' multiple=true accept=".zip" button type='submit' zipから作成
これで create_item_by_zip_path
に .zip
拡張子だけPost出来るようになりました。
zipファイルを展開する
rubyzipを入れる
まずzipファイルを展開するためのライブラリを入れます。
Gemfileに追記して bundle install
gem 'rubyzip'
もしくは、
gem install rubyzip
をして、 rubyzip
をインストールします。
zipを展開して保存するまで
zipfile = params[:zip_file] Zip::File.open(zipfile.path) do |zip| zip.each do |entry| ext = File.extname(entry.name) # 隠しファイルやゴミファイルは無視 next if ext.blank? || File.basename(entry.name).count(".") > 1 # テンポラリファイルを開く Tempfile.open([File.basename(entry.to_s), ext]) do |file| begin # 一時ファイルを作成 entry.extract(file.path) { true } # モデルを作成 image = Image.create!(source: file) ensure # 終わったらclose file.close! end end end
以上でpostしたzipファイルを展開して、処理する方法でした。一時ファイルはガベージコレクションのタイミングで自動的に削除されるようです。