Ruby on Railsでサーバーにファイルをアップロードしています
通常、これはテキストファイルであり、Submission ActiveRecordの「file」フィールドとして、提出のタイトルなどの他のフィールドとともにモデルに保存します。
ただし、ユーザーはZipファイルを送信することもできます。この場合、zipファイルを解凍し、Zip内の各ファイルに対して、同じテキストフィールドで現在のファイルを使用して新しい送信を作成する必要があります。
どうすればこれを達成できますか?
ネット上の解凍の例を見てみましたが、ほとんどはディレクトリを使用してファイルを解凍します。 SubmissionsControllerの現在のcreateメソッドのように、ファイルオブジェクトが受信され、Submission saveメソッドが呼び出されたときにファイルを保存するパスが自動的に生成されると仮定する必要があるかどうかはわかりません。だから、メモリ内でzipファイルを解凍してファイルオブジェクトの配列を取得し、同じファイルオブジェクトで同じフィールドを持つ新しいサブミッションを作成し、ActiveRecordにファイルパスを保存するときにそれぞれのファイルパスを生成させる必要があると考えていましたデータベース。 Rails and Ruby。
rubyzip gem を使用します。特にこの部分: https://github.com/rubyzip/rubyzip/blob/master/lib/Zip/filesystem.rb
Zipファイルの内容をミラーリングするメモリに人工的なファイルシステムを作成します。ドキュメントの例に基づいた例を次に示します。
Rubyzip interface changed!!! No need to do require "Zip/zip" and Zip prefix in class names removed.
require 'Zip'
Zip::File.open("my.Zip") do |zipfile|
zipfile.each do |file|
# do something with file
end
end
あなたの場合、アップロードされた一時ファイルの名前をmy.Zip
は例にあり、コンテンツをループして、それらに対して通常の操作を行うことができます。
RubyZipプロジェクトページから:
Rubyzipインターフェースが変更されました!!!クラス名の「Zip/zip」とZipプレフィックスを削除する必要はありません。
したがって、@ ben-leeのサンプルコードは次のように更新する必要があります。
require 'Zip'
Zip::File.open("my.Zip") do |zipfile|
zipfile.each do |file|
# do something with file
end
end
rubyzip
gemをインストールしたら、このメソッドを使用してZipファイルを抽出できます。
require 'Zip'
def extract_Zip(file, destination)
FileUtils.mkdir_p(destination)
Zip::File.open(file) do |Zip_file|
Zip_file.each do |f|
fpath = File.join(destination, f.name)
Zip_file.extract(f, fpath) unless File.exist?(fpath)
end
end
end
次のように使用します:
extract_Zip(zip_path, extract_destination)