てらさわと言います。

一旦ファイルに掃くと渡せますね。
(ファイルに掃かない方法もあるかもしれませんが)


面白そうなので手元で実装してみました。
tmpdirで実装してみましたが、actionの最後に消す方法が分かりませんでした。
一時的なディレクトリは適当に一意になるように作成し定期的に消すなどで
対応できそうだなぁと思ったので深追いしていません。

zipもgemがありそうですね。

  def download_images
    @tmpdir = Dir.mktmpdir
    begin
      Dir.chdir(@tmpdir) do
        # dbから画像を読み込み出力
        Dir.mkdir('download')
        Image.all.each do |image|
          open("download/#{image.filename}", 'wb') {|f| f.puts image.file }
        end

        # 圧縮
        system("zip -r download.zip download")

        # download
        send_file("#{@tmpdir}/download.zip", filename: 'download.zip',
          type: 'application/zip')
      end
    ensure
      # ここがうまくいかない
      # FileUtils.remove_entry_secure tmpdir
    end
  end




2014年2月9日 7:26 Nobukazu TAKAI <nocturne_2_eflat_9_2@me.com>:
前島様

早速お答え頂き、有り難うございます。

もう少しだけ教えてください。
データベースに格納されているデータをどうやって tar などのコマンドにわたせばよいのでしょうか?
これが分からずに、巡り巡って質問の方法にたどり着いたので。。。


On 2014/02/08, at 23:20, 前島真一 <netwillnet@gmail.com> wrote:

> 前島です。
>
> 無理にRubyで圧縮しようとせずに、Kernel#system メソッドを使って、tar や gzip コマンドなどを呼び出すと良いと思います。
>
>
> 2014年2月8日 22:11 Nobukazu TAKAI <nocturne_2_eflat_9_2@me.com>:
> 皆様
> 次のようなことをしたいのですが、できずに詰まっているのでご助言を頂きたくメールしました。
> [やりたいこと]
> データベースに登録されている PDF データを ZIP or TAR で1つのファイルをまとめてからダウロードするアクションを作る
> チェックされた本のPDF をダウンロードしたいです。
>
> book model ( title, abstract, author )
> has_one :pdf
>
> pdf model ( data, content_type, filename, book_id )
> belongs_to :paper
>
> app/views/books/index.html.erb
> ...
> <%= form_tag(:action=> 'download_pdf') do -%>
>   <% @books.each do |book| -%>
>     <td><%= book.title -%></td>
>     <td><%= book.abstract -%></td>
>     <td><%= book.author -%></td>
>     <td><%= check_box_tag "checked_items[#{book.id}]", book.id %></td>
>   <% end -%>
>   <%= submit_tag "チェックした項目の PDF をダウンロード" %>
> <% end -%>
>
> とりあえず、圧縮をせずにファイルを次々にダウンロードしようかと以下のような controller を作成したのですが、
> Render and/or redirect were called multiple times in this action.
> というエラーが出て、うまくいきませんでした。
> 1つだけチェックボックスをチェックしたときにはファイルをダウンロードできたのですが。
> そこで、send_data を実行する前に対象のファイルを1つにまとめてしまえば、全て解決!かと思い、ネットで検索するのですが、思うようなサイトに当たりません。
> rubyzip などあることは見つけたのですが、情報が少なくて思うように使えませんでした。
>
> app/controllers/books_controller.rb
>
>   def download_pdf
>     if params[:checked_items].present?
>       items = params[:checked_items].keys
>       items.each do |item|
>         @book= Book.find(item)
>         if @book.pdf.present?
>           send_data @book.pdf.data, type: @book.pdf.content_type, disposition: "attachment", filename: @paper.pdf.filename
>         end
>       end
>     else
>       redirect_to :admin_papers, notice: 'チェックされていなかったよ'
>     end
>   end
>
> ご助言を宜しくお願い致します。
>
>
>
> --
> 前島 真一(@netwillnet)
> http://willnet.in/