Rails6 のちょい足しな新機能を試す34(send_data filename オプション編)


はじめに

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 だけにします。


config/routes.rb

Rails.application.routes.draw do

resources :fruits, only: :show
end


controller を編集する

FruitsControllershow メソッドを追加します。

show メソッドの中で、 ファイル名を 果物の絵文字.txt で、ファイルの中身がその果物の英語になるようにして send_data メソッドを呼び出します。


app/controllers/fruits_controller.rb

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


参考情報