RailsでWebページを作るAction Viewについて学んでみた
はじめに
このコラムは、Ruby初心者の著書が、Railsガイド(http://railsguides.jp/)に沿って、リアルタイムで勉強をしていくコラムです。全12回を予定しています。勉強する上でつまずいた点やその回避法、他のプログラミング言語や職業経験に基づいたアドバイスなども紹介する予定です。RubyやRailsに興味のある方は、ぜひ一緒に勉強してみませんか。
今回参照するガイドはこちらです。
Action View の概要
http://railsguides.jp/action_view_overview.html
レイアウトとレンダリング
http://railsguides.jp/layouts_and_rendering.html
Action View フォームヘルパー
http://railsguides.jp/form_helpers.html
Action View の概要
ERBについて
RailsチュートリアルでもテンプレートにはERB(文書埋め込みRubyスクリプト)を使用しているので、まずはERBに慣れたいですね。アクションファイルやモデルファイルに書くものはRubyのコードでしたが、ビューファイルに書くものはテキストです。HTML用のファイルであれば、HTMLコードを書いていきます。ただしHTMLの中にRubyのコードを埋め込む必要性は多々あるので(ユーザーから受け取ったデータを出力するなど)、その際にはRubyのコードを「」で囲んで利用します。
以下は、Rubyのコードを埋め込む方法についてまとめたものです。Railsガイドで紹介されていないものは、ドキュメントで調べました。
コード「xxx」を実行します。出力はしません。
コード内で出力関数の「puts」を使っても、出力はされません。
コード | 出力 |
---|---|
#なし |
コード「xxx」を実行し、結果を出力します。「%>」という文字を出力したければ、閉じかっこの「%>」と間違われないようにするため、「%\>」とエスケープをする必要があります。
コード | 出力 |
---|---|
3 | |
" %> |
コード「xxx」を実行し、結果をエスケープせずに出力します。
コード | 出力 | ブラウザ上の表示 |
---|---|---|
注目!" %> | <b>注目!</b> | 注目! |
注目!" %> | 注目! | 注目! #太字です |
「xxx」はRubyのコメントになり、出力されません。
コード | 出力 |
---|---|
#なし | |
複数行のコメントもOK %> | #なし |
行頭までの空白を削除します。
後方の空白・改行を取り除きます。
コード | 出力 | ブラウザ上の表示 |
---|---|---|
\(^∀^) | (・∀・)/ \(^∀^) | (・∀・)/ \(^∀^) |
\(^∀^) | (・∀・)/\(^∀^) | (・∀・)/\(^∀^) |
行頭の空白と、後方の空白・改行を取り除きます。
「」は使用できますが、「」は使用できません。これらの空白除去は、テンプレートにコメント、if文、for文をはさんだり、
タグを利用したりする際、空白のせいで表示がずれてしまった場合などに使えます。</p> <p>以上の文法をまとめると、このようになります。</p> <p class="caption">ERBタグの種類と機能の差</p> <table> <tr><th>タグ</th><th>コードの実行</th><th>出力</th><th>前方空白削除</th><th>後方改行削除</th></tr> <tr><td><% ... %></td><td>あり</td><td>なし</td><td>なし</td><td>なし</td></tr> <tr><td><%= ... %></td><td>あり</td><td>あり(エスケープあり)</td><td>なし</td><td>なし</td></tr> <tr><td><%== ... %></td><td>あり</td><td>あり(エスケープなし)</td><td>なし</td><td>なし</td></tr> <tr><td><%# ... %></td><td>なし</td><td>なし</td><td>なし</td><td>なし</td></tr> <tr><td><%- ... %></td><td>あり</td><td>なし</td><td>あり</td><td>なし</td></tr> <tr><td><% ... -%></td><td>あり</td><td>なし</td><td>なし</td><td>あり</td></tr> <tr><td><%= ... -%></td><td>あり</td><td>あり(エスケープあり)</td><td>なし</td><td>あり</td></tr> <tr><td><%== ... -%></td><td>あり</td><td>あり(エスケープなし)</td><td>なし</td><td>あり</td></tr> <tr><td><%- ... -%></td><td>あり</td><td>なし</td><td>あり</td><td>あり</td></tr> </table> <h2><a id="h1-3"></a>パーシャルの命名ルールについて</h2> <p>テンプレートファイルから別のテンプレートファイル(パーシャル)を読み込む方法ですね。複数のページに共通する部分などを抜き出してパーシャルを作成しておくと、その共通部分に変更があった場合でも、修正が一ヶ所で済むのでとても便利です。</p> <p>次のコードはすべて同じファイルを呼び出します。</p> <div class="caption-code"> <p class="caption">#/path/to/app/views/static_pages/about.html.erb</p> <pre class="brush:xml;" type="syntaxhighlighter"><%= render "footer" %> <%= render " footer.html.erb" %> <%= render "static_pages/footer " %> <%= render partial: " footer " %> <%= render partial: "static_pages/footer " %> <%= render "static_pages/footer.html.erb" %> <%= render file: "/path/to/app/views/static_pages/_footer " %> <%= render file: "/path/to/app/views/static_pages/_footer.html.erb" %>
asとobjectオプション
テンプレートファイルから別のテンプレートファイルを呼び出す際に、データを渡したいことはよくあります。その場合の手法ですね。
例として、以下のテンプレートファイルを用意します。何かの名前を入力するフォームですね。この場合、引き渡しに必要なデータは「item」という名前のオブジェクト(name属性を持っている)です。
それではこのformパーシャルを呼び出してみましょう。最初は失敗するパターンから書いていきます。
#new.html.erb(@item = Item.first() というデータがあるとします)
これは以下の呼び出し方と同じです。
しかしこれでは、formパーシャルにitemというデータが渡ってきません。代わりにformというデータ(中身は@form)が渡されます。少し書き直してみましょう。
これは以下の呼び出し方と同じです。
formパーシャルにitem変数が渡されるようになりましたが、中身のデータがありません。さらに書き直してみましょう。
これは以下の呼び出し方と同じです。
これでやっと、@itemデータが入ったitem変数をformパーシャルに渡すことができました。
まとめるとこのようになります。
コレクションを出力する
同じテンプレートを繰り返し使いたいこともありますよね。たとえば、会社概要画面で新商品一覧情報を表示する際などです。その場合、それぞれの商品紹介のデザインを同じにするため、パーシャルを利用します。
例として、Productモデルから検索した商品の一覧を表示してみます。
案1:パーシャルの中でループを回し、ループ内で情報を出力する
どうでしょう。もっといい書き方はあるでしょうか。
案2:呼び出し元テンプレートの側でループを回し、ループ内でパーシャルを呼び出す
この書き方は、案1よりもパーシャルの再利用をしやすいような気がします。
案3:ループを書かずに、コレクションを使う
案2と同じ処理内容ですが、ループの部分を「collection」を使って表しています。パーシャルで使用している「product」という変数はパーシャルファイル名の「_product.html.erb」を元に決められます。パーシャルに渡すデータが「@products」でも「@items」でも、「product」という名が使われます。
また、パーシャルの呼び出し部分では、以下のような短縮形も使用できます。
ただしこの場合、呼び出されるパーシャルファイルは「products/_product.html.erb」に決め打ちになります。変数名が「@products」であろうと「@items」であろうと、そのインスタンスが指しているモデル(この場合はProduct)の名前を元に決められます。