Ruby on Railsで構築するWebシステムにファイルをダウンロードする機能を作るなら、HTMLでよく使われる方法ではなく、Ruby on Railsに用意されているメソッドを利用してください。ただしこの機能を使うためには、HTMLのタグだけではなくコントローラへの記述も必要です。
今回はRuby on Railsでファイルダウンロードを実装するための方法について紹介します。
HTMLにおけるダウンロードの基本
Ruby on RailsにはWebシステムで必要とされる基本的な機能が備わっており、その中にはファイルをダウンロードする機能も含まれます。ただし、それはHTMLのアンカータグを使ったファイルのダウンロード方法でけとは限りません。
Ruby on Railsのファイルをダウンロードする機能を紹介する前に、HTMLのアンカータグを利用したファイルをダウンロードする基本的な機能の作り方について説明します。
aタグでダウンロードするリンクを作る
aタグ(アンカータグ)は、HTMLでページ遷移に使われるタグですが、download属性を指定することでリンク先のファイルをダウンロードする機能にも使えます。
ダウンロードリンクの作り方
<a href=”対象ファイル名” download>リンク文字列</a>
または
<a href=”対象ファイル名” download=”ダウンロードファイル名”>リンク文字列</a>
ダウンロードリンクの例
<a href="./sample.pdf" download>ダウンロード</a>
なお、aタグでdownload属性を指定せずにテキストファイルを指定すると、Webブラウザはそのテキストを開きます。しかし、download属性を指定すると、対象ファイルがテキストファイルでも、それがWebブラウザで表示されることなくダウンロード可能です。
aタグでダウンロードするボタンを作る
先ほどaタグ(アンカータグ)でダウンロードするリンクの作り方を紹介しましたが、リンク文字列の代わりにボタンを配置すれば、ちょうどボタンを押すとファイルをダウンロードする機能を作れます。
ダウンロードボタンの作り方
<a href=”対象ファイル名” downloadgt;<buttongt;ボタンの名称</buttongt;</agt;
ダウンロードボタンの例
<a href="./sample.pdf" downloadgt;<buttongt;ダウンロード</buttongt;</agt;
JavaScriptで作る
先ほどアンカータグの中でボタンを使用する方法を紹介しましたが、同じ機能をJavaScriptでも作れます。その場合、ボタンタグのonClick属性を使ってJavaScriptを呼び出し、そこでアンカータグと同じ機能を実行します。
具体的にはボタンタグのonClick属性にJavaScriptの関数名を指定します。そして、そのJavaScriptの関数には、アンカータグを作成するcreateElement(“a”)のオブジェクトを作成し、そのhref属性とdownload属性にロード対象ファイルのURLを指定します。そしてclick()でアンカータグをクリックした状態にし、指定したファイルをダウンロードします。
JavaScriptでダウンロードする例
<button onClick='downloadone()'gt;ダウンロード</buttongt; <scriptgt; function downloadone() { var a = document.createElement("a"); document.body.appendChild(a); a.href = 'sample.pdf'; a.download = 'one.pdf'; a.click(); } </scriptgt;
Railsでaタグを作って実現する
先ほど、HTMLとJavaScriptを使ったダウンロードボタンの作り方を紹介しましたが、Ruby on Railsの仕組みの中にダウンロードするファイルを用意し、それをURLで指定することはできません。
Ruby on Railsでは、組み込まれた機能を利用してファイルをダウンロードする機能を作らなければありません。次からその仕組みと実装例を紹介します。
Railsでaタグを作るには
先ほどHTMLのaタグ(アンカータグ)でファイルをダウンロードするためのリンクの作り方を紹介しましたが、Ruby on Railsでaタグ(アンカータグ)を実現するために使うのがlink_toメソッドです。そしてlink_toメソッドはHTML属性を指定できるので、ここにdownload属性を指定することで、ファイルをダウンロードするためのリンクを作れます。
link_toの基本
link_to リンクテキスト, パス [, オプション, HTML属性] )
link_toメソッドを使った例(app/viewsの下のindex.html.erbなどに記述する例)
<%= link_to 'sample.pdf download', '/pdf/sample.pdf', download: 'sample.pdf' %>
上の例で生成されるHTML
<a download="sample.pdf" href="/pdf/sample.pdf">sample.pdf</a>
link_toの文字をボタンにする
先ほど、link_toメソッドでdownload属性付きのaタグ(アンカータグ)を作る方法を紹介しましたが、この方法ではリンク文字が表示されるだけでボタンではありません。CSSでリンク文字を修飾してボタンのように見せることが可能です。そしてlink_toメソッドではid属性も指定できます。
CSSを利用してボタンのように見せる場合の例
<%= link_to 'sample.pdf download', '/pdf/sample.pdf', download: 'sample.pdf' %>
上の例で生成されるHTML
<a download="sample.pdf" id="down_button" href="/pdf/sample.pdf"gt;sample.pdf</a>
ボタンを押してダウンロードする
先ほどRuby on Railsのlink_toメソッドを利用してダウンロードボタンを作る方法を紹介しましたが、この方法はリンク文字列をボタンのように見せているだけで、ボタンを作っている訳ではありません。
Ruby On Railsにはボタンを作る機能button_toメソッドも用意されています。次からbutton_toメソッドの使い方について紹介します。
Ruby on Railsのbutton_toを使う
Ruby on RailsにはHTMLの生成に使える便利なViewヘルパーが揃っていますが、今回紹介するbutton_toもそのようなViewヘルパーの1つです。そして、button_toはボタンでリンクを生成するViewヘルパーです。
button_toの使い方
button_to(文字列 [, オプション, データ属性 or HTML属性 or イベント属性])
なおbutton_toはフォームの送信ボタンを生成します。このボタンによるファイルをダウンロードする仕組みを作るには、Ruby on Railsのコントローラにファイルをダウンロードさせる仕組みを組み込みます。
ファイルをダウンロードするbutton_toの使用例
<%= button_to "ボタン", {controller: 'download', action: 'file_download'}, {method: :get} %>
この例では、「ボタン」という文字が表示されるボタンを作成し、これを押すと「download」というコントローラに含まれる「file_download」が実行されます。そして、ファイルのダウンロード機能をコントローラに記述します。
コントローラでsend_fileを使う
Ruby on Railsのsend_fileメソッドは、指定したパスに存在する画像やファイルを読み込み、その内容をクライアントに送信する機能を提供します。
send_fileメソッドの使い方
send_file(ファイルのパス [, オプション])
先ほど、button_toヘルパーでコントローラに定義された機能を実行すると説明しましたが、そこでsend_fileメソッドを使います。
先ほどの例で使われていた「download」というコントローラに含まれる「file_download」は、次のように記述します。
class DownloadController < ApplicationController def index end def file_download download_file_name = "public/master.txt" send_file download_file_name end end
この例では、ボタンを押すとsend_fileにより、「public/master.txt」がダウンロードされます。
ルーティングを設定する
Ruby on Railsのビューとコントローラの記述方法を紹介しましたが、それらにWebブラウザからアクセスするにはルーティング設定が必要です。config/roites.rbに次のようにルーティングを設定します。
ボタンでダウンロードするためのルーティングの設定例
get "/download", to: "download#index" get "file_download", to: "download#file_download"
この例は、Webブラウザから「/download」をアクセスすると、「download」というビューのindex.html.erbを表示する例と、そのビューに記述されたボタンのactionに指定された「file_download」にアクセスするための例です。
まとめ
これまで紹介したようにHTMLで使えたファイルをダウンロードするためのタグがRuby on Railsでもそのまま使えるとは限りません。そのような場合は別の方法を検討しましょう。
なおRuby on Railsには、今回紹介したようにファイルをダウンロードする機能を実装するための便利なメソッドがあります。ぜひ、こういったメソッドをうまく利用してください。