send_file / send_data
send_file を使います。
hoge_controller.rb
def download
filepath = Rails.root.join('app', 'pdfs', 'hoge.pdf')
stat = File::stat(filepath)
send_file(filepath, :filename => 'hoge.pdf', :length => stat.size)
end
send_data というのもあります。
両者の違いは、メモリ内に展開済みのデータを送信するか、ファイルをそのまま送信するかの違いです。
send_dataの場合、メモリを使いますが、一時ファイルを作成してすぐに削除ができます。
hoge_controller.rb
require 'zipruby'
def download_zip
users_csv = User.generate_csv
tmp_zip = Rails.root.join('tmp', 'zip', filename).to_s
Zip::Archive.open(tmp_zip, Zip::CREATE) do |ar|
ar.add_buffer('users.csv', users_csv)
end
# ここでsend_fileだと、後の File.delete で
# ファイルを削除してから送信するので動作しない
# send_file(filepath, :filename => 'hoge.zip')
# メモリ内に展開した
send_data(File.read(filepath), :filename => 'hoge.zip')
# 一時ファイルを削除してOK
File.delete tmp_zip
end
filename を指定しても効かない
日本語だとダメみたいです。エンコードします。
file_name = "日本語.txt"
file_name = ERB::Util.url_encode(file_name)
send_file(filepath, :filename => file_name, :length => stat.size)