【Rails入門説明書】link_toについて解説
はじめに
RailsアプリケーションはWebアプリケーションですので、画面の移動は原則としてリンクです。
そのため、ビューファイルにリンクを埋め込めば良いのですが、ただHTMLを埋め込むのではなく、メソッドを埋め込んで実装するのが原則でしょう。
そんなときに利用するのが、link_toメソッドです。
おそらく、Railsアプリケーションを作っていく中での使用頻度としては、1、2を争うほど使っていくことになるメソッドとも言えます。
今回は、そんな身近で使い勝手のあるlink_toメソッドについて、詳しく解説していきましょう。
Ruby on Railsとは?4つの作れるものや人気の理由・学習方法を解説
link_toを使えば、リンクを埋め込める
link_toを使えば、リンクを埋め込めます。HTMLで言うところ、「aタグ」を生成してくれるメソッドです。
例えば、もっとも単純な動きとしては、以下のようになります。
(ビューファイル)
(出力されるaタグ)
上記のように、基本的には、表示上の文言と移動先のURLを設定することで、ブラウザ上でリンクとなるaタグを生成してくれます。
しかし、上記の使い方であれば、HTMLで固定リンクを記載するのと何ら変わりません。
link_toは、もっと柔軟に変化させられるポテンシャルを秘めているのです。
link_toでできること
link_toには、ただ決まったリンクを生成するだけではなく、代表的なものだけでも以下のような機能があるのです。
URLやパスを指定したリンクを生成する
前述で紹介した、link_toの基本です。
もちろん、外部のURLだけではなく、内部の別ページのリンクも指定することができます。
また、Railsでは表示文言やURLを動的に生成することができますので、ただ固定リンクを張りつけるだけではありません。
ルーティングの名前でリンクを指定する
Railsの特徴的な機能の1つ「ルーティング」では、HTTPリクエスト(HTTPメソッド)とURLごとに、特定のアクションを行わせることができます。
そして、その組み合わせに対して、「名前」を付けることができるのです。
※ルーティングについては、<a href=”https://web-camp.io/magazine/archives/16815″>【Rails入門説明書】routesについて解説</a>を参照してください
link_toは、その名前をリンクとして指定することができます。
こうすることで、仮にルーティングが変わったとしても、ビューファイルを変更することなく、routesファイルを編集するだけで済みますので、メンテナンス性が向上します。
パラメータを渡すことができる
link_toでは、任意のパラメータを渡すこともできます。
外部サイトへのアクセスで必要なパラメータはもちろん、自プログラムのアクションへ引数としてパラメータを渡して処理をするなど、応用範囲は広いでしょう。
多彩なオプションを付与できる
aタグでリンクを生成する場合、class指定やtarget指定、リンク先のMIMEタイプなどを指定することができます。
link_toでも、同様の指定を行うことができますので、CSSでのスタイル設定なども容易です。
ブロックを使って複雑なリンクも作成可能
HTMLで作ることができるdiv全体のリンクや、アイコン表示なども、do~endブロックを使って表現可能です。
以上のように、link_toはaタグでできることをすべて表現でき、なおかつメンテナンス性も高めてくれます。
もっともっと活用していきましょう。
link_toの使い方
前述までに紹介したそれぞれの機能について、具体的な実装方法(使い方)を説明していきます。
テスト環境の準備
その前に、テスト環境を作って動作確認ができるようにしておきましょう。
scaffoldとbootstrapを使って、lt_testというアプリケーションを生成します。
1.以下のコマンドで、Railsアプリケーションのひな型を作成します。
[bash] &amp;gt; rails new lt_test &amp;gt; cd lt_test &amp;gt; rails generate scaffold User name:string email:string phone:string &amp;gt; rake db:migrate [/bash]2.bootstrapのインストール 以下の2行をGemfileに追記してください。
gem ‘bootstrap-sass’, ‘~&amp;gt; 3.3.7’ gem ‘sass-rails’, ‘&amp;gt;= 3.2’
※sass-railsは、すでにGemfileに記載があれば不要ですが、 以下のコマンドでインストールできます。
[bash] &amp;gt; bundle install [/bash]3.bootstrapの初期設定 以下の3ファイルを修正してください。 (app/assets/stylesheets/application.css)
[css] * — commentout(delete”=”) * require_tree . * require_self */ // — bootstrap import — add @import “bootstrap-sprockets”; @import “bootstrap”; [/css]修正後、拡張子を「scss」に変更しておきます。 (app/assets/javascripts/application.js)
[su_list icon="icon: check"]
- 上級者からWebデザイナーまでが使える言語
- 多くも実行エンジンが存在し、処理速度を向上するための工夫が行われている
- 環境を整えるのが容易である
[/su_list]
(/app/views/layouts/application.html.erb)
※なお、【Rails入門説明書】Bootstrapについて解説に詳細が記載されていますので、参照してください
4.テストデータの登録
サーバを起動し、ブラウザからテストデータを3件ほど登録しておきましょう。
[/bash]
(localhost:3000/users)
URLやパスを指定したリンクを生成する
まずは、link_toのもっとも基本的な使い方です。
この方法で使用する場合の基本的な構文は、以下になります。
link_to ‘表示する文字列’, ‘リンク先のURL(パス)’
冒頭でも紹介した通り、表示する(リンクになる)文字列と、移動先のURLを引数にします。
テスト環境のリスト表示画面に、冒頭で消化したGoogleへのリンクを追加してみましょう。
変更するのは、「app/views/users/index.html.erb」です。
(app/views/users/index.html.erb)
&lt;%= link_to ‘New User’, new_user_path %&gt;
&lt;br&gt; &lt;!– (1) –&gt;
&lt;%= link_to ‘Google Search’, ‘https://www.google.co.jp’ %&gt; &lt;!– (2) –&gt;
一番下のNew Userのリンクの下へ(1)(2)を追加します。((1)は見やすくするための改行です)
HTMLを確認すると、(2)の部分は、以下のように変換されています。
同様に、内部リンクのパス指定も行えますので、それも試してみましょう。
(app/views/users/index.html.erb)
&lt;%= link_to ‘New User’, new_user_path %&gt;
&lt;br&gt; &lt;!– (1) –&gt;
&lt;%= link_to ‘Google Search’, ‘https://www.google.co.jp’ %&gt; &lt;!– (2) –&gt;
&lt;br&gt; &lt;!– (3) –&gt;
&lt;%= link_to ‘Const New User’, ‘/users/new’ %&gt; &lt;!– (4) –&gt;
(4)の指定で、Rails内の新規作成ページへ遷移します。
しかし、同じ新規作成ページでも、もともとあったものと記載方法が違っている点に注意してください。
Railsアプリケーションでは、基本的に(4)のような内部リンクの固定パス指定を行いません。それは、次で紹介するルーティングを利用するためです。
ルーティングの名前でリンクを指定する
Railsでは、ルーティングを使って各種ページへの遷移を管理しています。そのため、仮に内部的なディレクトリ構成の変更があった場合でも、routesファイルのみを修正することで対応することができるわけです。
このルーティングの設定には、名前を付けることができます。link_toは、その名前を使ってリンクを作ることができるのです。
ではまず、テスト環境のルーティングの設定を確認してみましょう。
[bash] &gt; rake routes[/bash]
上記のコマンドで、以下のようなルーティング設定の一覧が表示されます。(他にも表示されますが、今回必要な部分のみ抜粋しています)
[bash] Prefix Verb URI Pattern Controller#Actionusers GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
:
[/bash]
この中で、「Prefix」の部分が、ルーティングに付けられた名前です。(空欄のものは名前が付けられていません)
link_toは、この名前を使って、リンクを生成することができるのです。その場合の構文は以下のようになります。
link_to ‘表示する文字列’, ルーティングの名前_path
名前をそのまま使うのではなく、「_path」を付与する点に注意してください。
実際のプログラムコードについては、すでにscaffoldが自動で生成してくれています。例えば、一覧画面の下に最初からあった「New User」のリンクは、以下のような記載になっているのです。
(app/views/users/index.html.erb)
&lt;%= link_to ‘New User’, new_user_path %&gt;
前述しているルーティングのリストを見ると、新規作成画面である「/users/new」へのルーティングには、「new_user」という名前が付けられていますので、link_toでは、「new_user_path」と指定しているわけです。
こうすることで、仮にディレクトリ構成が変わったとしても、複数のビューファイル(index.html.erbなど)を修正する必要がないため、メンテナンス性が上がるわけです。
パラメータを渡す
「New User」以外の、行ごとに表示されているリンク「Show」「Edit」「Destroy」についても、ルーティングの名前を使ってリンクを生成しています。
(app/views/users/index.html.erb)
&lt;% @users.each do |user| %&gt;
&lt;tr&gt;
:
&lt;td&gt;&lt;%= link_to ‘Show’, user %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= link_to ‘Edit’, edit_user_path(user) %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= link_to ‘Destroy’, user, method: :delete, data: { confirm: ‘Are you sure?’ } %&gt;&lt;/td&gt;
:
しかし、実際にはこれらのリンクは「New User」のように固定されているわけではなく、行によって表示されるURLが違っているのです。(ブラウザ上のリンクにカーソルを当てて、ブラウザの下端に表示されるURLを確認すれば、違っていることが分かります)
その行による違いを指定するために、パラメータを渡しているのです。
パラメータを渡す場合の構文は、以下のようになります。
link_to ‘表示する文字列’, ルーティングの名前_path(パラメータ)
index.html.erbの例で言えば、Editリンク指定のルーティング名にある「(user)」です。
なお、このuserは、Entryオブジェクトと呼ばれるActiveRecordオブジェクトで、ルーティング設定の名前ではありません。
Entryオブジェクトは、アクションが定義されているコントローラで付与されているもので、リストの中のどのデータが指定されたのかの情報が格納されています。
ここで設定されているEntryオブジェクト「user」は、その上の「」のブロック引数「user」です。(可読性を考慮すれば、このブロック引数の名前はあまり良い例ではありません)
※インスタンス変数の「@user」は、コントローラのindexメソッドで取得しています。
ルーティングの名前は省略できる?
ここまでの説明を読んで、多くの人が「Show」と「Destroy」のリンクで設定されている「user」に疑問を持っていると思います。
「user」という指定だけで、「_path」が付与されていませんし、まるで、Entryオブジェクトだけの記載のようにも見えます。
じつは、この2か所の「user」は、「user_path(user)」の略なのです。
試しに、以下のように修正しても、正しく表示されます。
(app/views/users/index.html.erb)
&lt;td&gt;&lt;%= link_to ‘Show’, user_path(user) %&gt;&lt;/td&gt;
:
link_toのルーティング設定の名前を使ったURL指定では、「Show」と「Destroy」のようにID指定だけで生成されるURLは、Entryオブジェクトだけ記載しても良いことになっているのです。
なお、ID指定だけで生成されるURLというのは、ルーティング設定の「URI Pattern」が「モデル名の複数形の/:id」になっているものです。
外部リンクのパラメータ(クエリー)
内部リンクのパラメータについては、上述のようにハッシュで指定することで渡すことができますが、外部リンクの場合は、どうすれば良いのでしょうか。
例えば、Google検索した結果のURLとなる、以下のようなクエリー付きのリンクを生成させたいときの対応方法です。
「https://www.google.co.jp/search?q=Taro」
じつは、その場合のもっとも単純な方法は、URLの文字列を自分で作ることです。
ただし、この場合、名前で検索するリンクを「https://www.google.co.jp/search?q=Taro」と直接指定するのは、メンテナンス性が著しく落ちますので、「’https://www.google.co.jp/search?q=’ + user.name」と、Entryオブジェクトから取得するようにすべきでしょう。
以下の(5)の行を追記することで、一覧の行ごとに名前でGoogle検索した結果のリンクを付けることができます。
(app/views/users/index.html.erb)
&lt;td&gt;&lt;%= link_to ‘Destroy’, user, method: :delete, data: { confirm: ‘Are you sure?’ } %&gt;&lt;/td&gt;&lt;/span&gt;
&lt;td&gt;&lt;%= link_to ‘Google Search’, ‘https://www.google.co.jp/search?q=’ + user.name %&gt;&lt;/td&gt; &lt;!– (5) –&gt;
&lt;/tr&gt;
:
HTTPリクエスト(HTTPメソッド)の指定
改めて、テスト環境のルーティング設定を見てみましょう。
[bash] Prefix Verb URI Pattern Controller#Actionusers GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
:
[/bash]
ここにある、ルーティング設定に名前が設定されていないものについて、どう設定するのでしょうか。
ポイントは、GETやPOST、DELETEといった、HTTPリクエスト(HTTPメソッド)です。
scaffoldで自動設定されるルーティングでは、URIが同じでGETリクエスト以外のものについて、名前が付いていません。これは、名前指定のURLでは、そのままでは「GETリクエスト」として処理されるからなのです。
つまり、GETリクエスト以外のルーティングについては、HTTPリクエストを指定してやる必要があるということになります。
そのときに使用するのが、「methodオプション」です。
実際に、テスト環境にあるDestroyのリンクは、そうした設定になっています。
(app/views/users/index.html.erb)
&lt;td&gt;&lt;%= link_to ‘Destroy’, user, method: :delete, data: { confirm: ‘Are you sure?’ } %&gt;&lt;/td&gt;
:
「user(= user_path(user))」でURLを指定し、methodオプションで、「:delete」を指定しているわけです。
確認ポップアップの表示
Destroyリンクのlink_toを、もう一度確認しましょう。
(app/views/users/index.html.erb)
&lt;td&gt;&lt;%= link_to ‘Destroy’, user, method: :delete, data: { confirm: ‘Are you sure?’ } %&gt;&lt;/td&gt;
:
Destroyリンクのlink_toには、dataオプションが設定されています。
この設定で、Destroyのリンクをクリックしたときに表示される、確認ポップアップを指定しています。そのときに表示される文言は、confirmオプションに渡している文字列です。
class定義
scaffoldは、最低限のひな型を作ってくれますが、残念ながらスタイルまでは対応してくれません。
そのため、事前にbootstrapを導入していますが、それでも勝手に設定してくれるわけではありません。
つまり、自分でスタイル設定しなければ、見た目を変えることはできないのです。(実際、ここまでに確認した一覧表示も、お世辞にもきれいなものとは言えないものだと思います)
そのため、CSSでスタイルを定義して、class設定していきましょう。class設定についても、link_toのオプションで対応できるのです。
テスト環境にスタイル設定をしてみましょう。
&lt;%= link_to ‘New User’, new_user_path, class:”btn btn-primary” %&gt;
:
ブラウザで読み込みなおすと「New User」のリンクがボタンになっています。(”btn btn-primary”はbootstrapで定義されているスタイルです)
その他のオプション
link_toはオプション設定をすることで、ここまでに説明した以外にも柔軟な対応を行うことができます。
オプションを含んだ構文は、以下のようになります。
link_to ‘表示する文字列’, URL [, オプション名: パラメータのシンボル, HTMLオプション名: パラメータのシンボル,,,]
link_to ‘表示する文字列’, URL [, オプション =&gt; パラメータのシンボル, HTMLオプション =&gt; パラメータのシンボル,,,]
link_to ‘表示する文字列’, URL [, オプション名: “パラメータ”, HTMLオプション名: “パラメータ”,,,]
※HTMLオプション設定は複数設定可能です。また、記載方法は、上記のどの書き方でも構いません
:オプション名 | 説明 |
---|---|
:data | DATA要素 |
:method | HTTPメソッド(:get, :post, :put, :delete)の指定 |
:remote | Ajaxでリンクを処理 |
:HTMLオプション名 | 説明 |
---|---|
:name | アンカー名 |
:href | リンク先 |
:hreflang | リンク先の言語コードを指定 |
:type | 関連ファイルのMIMEタイプを指定 |
:media | 関連ファイルの出力メディアのリンクタイプ |
:rel | この文章から見た、href属性で指定するリンク先の役割 |
:rev | href属性で指定するリンク先から見た、この文章の役割 |
:charset | 関連ファイルの文字コード |
:shape | ホットスポット領域の形状 |
:coords | ホットスポットの形状の座標 |
:target | 別ウインドウで表示する |
:id | 要素固有の識別子 |
:class | 要素を分類するクラス名 |
:title | 要素の補足情報 |
:style | 要素の補足情報 |
:dir | 表記方向 |
:lang | 基本言語 |
ブロックを使って複雑なリンクも作成可能
div全体のリンクや、アイコン表示については、前述のオプションだけでは対応が難しくなります。そのため、link_toはブロックを使うこともできるようになっているのです。
その場合の構文は、以下の通りです。
リンクになるタグや文字列
&lt;% end %&gt;
ブロックを利用する場合、ブロック内がリンクになるため、link_toの第1引数は文字列ではありません。注意してください。
先ほど各行に追加したGoogle検索の要領で、電話番号の列に設定してみましょう。ここでは、電話番号の列に背景色を付けてみました
(app/views/users/index.html.erb)
&lt;td&gt;&lt;%= user.name %&gt;&lt;/td&gt;
&lt;td&gt;&lt;%= user.email %&gt;&lt;/td
&lt;td&gt; &lt;!– (6) –&gt;
&lt;%= link_to ‘https://www.google.co.jp/search?q=’ + user.phone do %&gt; &lt;!– (7) –&gt;
&lt;div class=”bg-success”&gt;&lt;%= user.phone %&gt;&lt;/div&gt; &lt;!– (8) –&gt;
&lt;% end %&gt; &lt;!– (9) –&gt;
&lt;/td&gt; &lt;!– (10) –&gt;
:
まとめ
今回は、Railsアプリケーションでリンクを生成するlink_toについて解説しました。
link_toは、Railsアプリケーションの画面遷移の基本で、使いやすさの重要なポイントでありますが、なによりメンテナンス性を決める要です。
Railsが用意してくれているルーティングの仕組みをうまく活用し、メンテナンス性の高いプログラムを作っていきましょう。
・link_toを使って、aタグを生成できる
・link_toのリンク先にルーティングの名前を利用するときは、名前に「_path」を付与する。
・Entryオブジェクトというのは、指定された行の情報を持つActiveRecordオブジェクト
・ID指定だけのURLはEntryオブジェクトの指定だけでURLを生成してくれる
・タグも含めてリンクにしたい場合は、ブロックを使う
・ブロックを利用する場合、文字列指定は不要