はじめに
Rails 6 に追加されそうな新機能を試す第34段。 今回は、 send_data filname オプション
編です。
Rails 6 では、 send_data, send_file の filename オプションを指定した場合、ファイル名を RFC 2231, RFC 5987 に従った形式で送信するようになりました。
Ruby 2.6.3, Rails 6.0.0.rc1 で確認しました。Rails 6.0.0.rc1 は gem install rails --prerelease
でインストールできます。
$ rails --version
Rails 6.0.0.rc1
rails プロジェクトを作る
$ rails new rails6_0_0rc1
$ cd rails6_0_0rc1
controller を作る
$ bin/rails g controller fruits
routes を編集する
今回は、 show だけにします。
Rails.application.routes.draw do
resources :fruits, only: :show
end
controller を編集する
FruitsController
に show
メソッドを追加します。
show メソッドの中で、 ファイル名を 果物の絵文字.txt
で、ファイルの中身がその果物の英語になるようにして send_data メソッドを呼び出します。
class FruitsController < ApplicationController
FRUITS = %w[grapes melon watermelon tangerine lemon].freeze
GRAPES = 0x1f347
def show
i = params[:id].to_i
filename = [GRAPES + i].pack('U*') + '.txt'
send_data FRUITS[i], filename: filename
end
end
rails server を実行する
$ bin/rails s
ブラウザからアクセスする
http://localhost:3000/fruits/0 にアクセスすると🍇.tx
がダウンロードされます(Chrome 75.0.3770.80 で確認しました)。
curl コマンドで Content-Disposition を確認する
curl コマンドで Content-Disposition を確認すると RFC 2231, RFC 5987 に従った形式になっていることがわかります。
$ curl --head http://localhost:3000/fruits/0
...
Content-Disposition: attachment; filename="%3F.txt"; filename*=UTF-8''%F0%9F%8D%87.txt
...
Rails 5 では
ブラウザ(Chrome 75.0.3770.80) で http://localhost:3000/fruits/0 にアクセスしたときは同じ動作ですが、 curl コマンドで Content-Disposition を確認すると違いがあります。
Content-Disposition: attachment; filename="🍇.txt"
試したソース
試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try033_cache_error