なりちゅうのエンジニアブログ

毎日学んだことをちょっとずつブログに書いていきます。

【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ファイルを展開して、処理する方法でした。一時ファイルはガベージコレクションのタイミングで自動的に削除されるようです。