FBCのチーム開発でイベントをical形式で出力するissueに取り組んでいます。
ファイルが出力されてカレンダーと同期できるところまでは一旦実装はできました。 しかし、私の要件確認ミスで考慮漏れがあったため追加対応中なのですが、一旦実装が終わったRailsでのファイルダウンロード機能について簡単にまとめておきたいと思います。
リファクタ前:renderメソッドのオプションで対応していた
実装当初は以下のように render
メソッドを使ってファイル出力の処理を書いていました。
※カレンダーのフォーマット処理の詳細は割愛します。
def index respond_to do |format| format.html format.ics do cal = IcalFormatExporter.export_calendar(set_export) render plain: cal.to_ical end end end
render
メソッドはブラウザに表示されるファイルの元となるファイルを指定できるメソッドです。
例えばcontrollerの update
メソッドで更新ができなかった場合に、以下のように edit
のテンプレートを呼び出すことができたり
def update @event = Event.find(params[:id]) if @event.update(event_params) redirect_to(@event) else render "edit" end end
render json: @event
カレンダーの出力も render
メソッドでレンダリング元のファイルを指定して、それが画面描画ではなく、ファイルで出力できるようにしました。
でもよくよく考えたら、今回やりたいことはファイルダウンロードであってレンダリングのファイルを指定することじゃないよなと考え直し、関連するコードを調べて修正しました。
リファクタ後:send_dataメソッドを使用する形で修正
ファイル出力といえばCSVを出力する実装はたくさんサンプルがあります。
その際によく利用されているのが send_data
メソッドでした。
def index respond_to do |format| format.html format.ics do cal = IcalFormatExporter.export_calendar(set_export) send_data((cal.to_ical), filename: 'カレンダー.ics', type: 'text/calendar; charset=UTF-8') end end end
これでレンダリングではなくファイルの出力として実装が可能です。
まとめ
リファクタ前のコードは実装前にCSV出力のサンプルなどを調べていれば書かなかったかもしれませんが、render
メソッドやそのオプションの意味を改めて調べる機会になって結果的には良かったです。
伊藤さんのアウトプットに関する発表で3日前の自分が喜ぶことを書こうという内容があり、初歩的な内容ではあるのですが備忘録的な意味も込めてリファクタ前後のコードを書いてみました(変なところはフィードバックいただけると嬉しいです!)
これからも書いて動かして調べてを積み重ねます〜!