6

現在、画像ファイルを zip ファイルから直接モデルに添付しようとしています (つまり、最初にディスクに保存せずに)。ZipEntry を Tempfile または File に変換してメモリに保存し、別のメソッドまたはオブジェクトを処理する方法を知っているオブジェクトに渡すためのより明確な方法があるようです。

これが私のコードです:

def extract (file = nil)
  Zip::ZipFile.open(file) { |zip_file|
    zip_file.each { |image|
      photo = self.photos.build
      # photo.image = image # this doesn't work
      # photo.image = File.open image # also doesn't work
      # photo.image = File.new image.filename
      photo.save
    }
  }
end

しかし、問題は、photo.image がモデルへの (ペーパークリップによる) 添付ファイルであり、何かを添付ファイルとして割り当てるには、何かが File オブジェクトである必要があることです。ただし、ZipEntry をファイルに変換する方法を理解することはできません。ファイルを開いたり作成したりする唯一の方法は、そのパスに文字列を使用することです。つまり、ファイルを特定の場所に抽出する必要があります。本当に、それはばかげているようです。ZipEntry ファイルを出力ストリームに抽出して、そこでファイルに変換できないのはなぜですか?

究極の質問: Zip ファイルから ZipEntry を抽出し、それを直接 File オブジェクトに変換 (または直接 Paperclip オブジェクトとして添付) できますか? それとも、最終的にはそのバージョンが削除されますが、アタッチする前にハードドライブに実際に保存するのに行き詰まっていますか?

UPDATE ブルーベリー畑のおかげで、私は自分の解決策に少し近づいたと思います. 追加したコード行は次のとおりです。これにより、必要な一時ファイル/ファイルが得られます。

photo.image = zip_file.get_output_stream image

しかし、私のPhotoオブジェクトは渡されたファイルを受け入れませんimage/jpeg。実際、content_typeファイルを確認すると、application/x-empty. これは、出力ストリームを取得すると、ファイルの末尾にタイムスタンプが追加されているように見えるため、最終的にimagename.jpg20110203-20203-hukq0n. 編集:また、作成する一時ファイルにはデータが含まれておらず、サイズが0です。したがって、これは答えではない可能性があります。

では、次の質問: これを取得して画像/jpeg ファイルを取得する方法を知っている人はいますか?

更新

私はこれでもう少し遊んでいます。出力ストリームは進むべき道ではなく、むしろ入力ストリームです(これは常に私を混乱させてきました)。ZipEntry で get_input_stream を使用して、ファイル内のバイナリ データを取得します。これを (ファイル オブジェクトとして) ペーパークリップの添付ファイルに入れる方法を理解する必要があると思います。ZipInputStream を添付ファイルに直接プッシュしようとしましたが、もちろんうまくいきません。抽出された ZipEntry をファイルとしてキャストしようとした人が誰もいないとは本当に信じがたいです。これが悪いプログラミング手法と見なされる理由はありますか? 一時ファイルのディスク書き込みをスキップすることは完全に受け入れられ、Zip アーカイブ管理などでサポートされているように思えます。

とにかく、問題はまだ残っています:

入力ストリームをファイル オブジェクト (または一時ファイル) に変換する方法はありますか? できれば、ディスクに書き込む必要はありません。

4

2 に答える 2

6

これを試して

Zip::ZipFile.open(params[:avatar].path) do |zipfile|
  zipfile.each do |entry|
    filename = entry.name
    basename = File.basename(filename)

    tempfile = Tempfile.new(basename)
    tempfile.binmode
    tempfile.write entry.get_input_stream.read

    user = User.new
    user.avatar = {
      :tempfile => tempfile,
      :filename => filename
    }
    user.save

  end
end
于 2011-08-05T11:15:52.927 に答える
0

ZipFile の get_input_stream および get_output_stream メッセージを確認してください。

于 2011-02-04T00:39:46.957 に答える