RailsでWebページを作るAction Viewについて学んでみた

2015年6月10日(水)
野田 貴子

パーシャル読み込み時にレイアウトを指定する

同じ商品一覧情報でも、埋め込む場所によってHTMLタグを変える必要があることもありますよね。たとえばサイドバーに埋め込むときは

  • タグで囲い、画面中央エリアに埋め込むときは
    タグで囲むなどのように。そういったときには、パーシャルの読み込み時にレイアウトを指定することができます。
    <%= render partial: 'post', layout: 'box', locals: {post: @post} %>
    

    このように書くと、まずパーシャルテンプレートの中のRubyの部分が実行され、HTMLが取得されます。続いてレイアウトテンプレートが、そのHTMLを「yield」部分(図1)に埋め込み、最終的なHTMLが出力されます。

    パーシャル読み込み時にレイアウトを指定

    図1:パーシャル読み込み時にレイアウトを指定

    また以下の図2のように、パーシャルテンプレートを指定せずに、レイアウトテンプレートだけを指定することもできます。

    レイアウトテンプレートのみを指定した例

    図2:レイアウトテンプレートのみを指定した例

    Action Viewが提供するヘルパーの概要

    ヘルパーとは、出力の手助けをしてくれる機能です。ルールに沿って書く必要がありますが、タグなどを一から書かずとも、必要なHTMLコードを補完してくれます。

    AtomFeedHelper

    名前の通り、Atomフィードを生成してくれるヘルパーです。こういうヘルパーは便利ですよね。XMLやFEEDは、カッコの数やカンマの位置が少し違うだけでエラーになってしまうので、自動で書き出してくれると助かります。

    content_for

    これは非常に便利な機能です。たとえば、プロジェクト詳細画面で「だけ」タイムラインを表示するためのJavaScriptライブラリを読み込みたい場合などに使えます(図3)。

    content_forを使うと便利な状況

    図3:content_forを使うと便利な状況

    よくある悪いプログラミング手法として、以下のように共通のテンプレートに個別のテンプレートのための条件分岐を書く方法があります。ですが、これでは個別のテンプレートの数だけ分岐が増え、カオスになってしまいます。また、他の関係のない画面用のコードも実行することになり、無駄になります。

    #共通テンプレート(良くない例)

    <head>
    <% if 会社概要画面ならば %>
      <script type="text/javascript" src="ccc.js">
    <% end %>
    <% if 商品一覧画面ならば %>
      <script type="text/javascript" src="aaa.js">
      <script type="text/javascript" src="bbb.js">
    <% end %>
    <% if 注文確認画面ならば %>
      <script type="text/javascript" src="ccc.js">
      <script type="text/javascript" src="ddd.js">
    <% end %>
    

    個別のテンプレートで必要なものは、個別のテンプレートの中に書いておくべきですよね。これを実現するのがcontent_forです(図4)。

    contnet_forの使用例

    図4:contnet_forの使用例

    DateHelper

    どのプログラミング言語を利用していても、日付を表す数値(タイムスタンプ)と文字列の取り扱いは、抑えておくべきでしょう。

    ローカライズされたビュー

    同じ画面にアクセスしても、I18n.localeに指定された条件によって、使用するテンプレートを切り替えることができます。I18n(国際化、internationalizationのこと。i+18文字+nが由来 )といえば、元は多言語化の仕組みですが、Railsの場合これは言語に限ったことではないようです。おもしろいですね。

    言語ごとに切り替え

    • show.html.erb(デフォルト)
    • show.en.html.erb(I18n.locale = :en(英語)のとき)
    • show.de.html.erb(I18n.locale = :de(ドイツ語)のとき)

    ユーザーの属性ごとに切り替え

    • show.html.erb(デフォルト)
    • show.admin.html.erb(I18n.locale = :admin(管理者)のとき)

    時間帯ごとに切り替え

    • show.html.erb(デフォルト)
    • show.night.html.erb(I18n.locale = :night(夜)のとき)

    「英語」かつ「管理者」のように併用はできませんが、利用の幅はとても広いと思います。

    レイアウトとレンダリング

    レスポンスを作成する

    サーバーからレスポンスの返し方が3つ紹介されていますが、文章が少し分かりにくいかもしれませんので、それぞれ解説したいと思います。

    (1)renderを呼び出し、ブラウザに返す完全なレスポンスを作成する

    HTMLページ、画像ファイル、RSSフィードなど、ブラウザに表示できる(またはダウンロードできる)形のものをサーバーからブラウザにレスポンスすることです。

    (2)redirect_toを呼び出し、HTTPリダイレクトコードステータスをブラウザに送信する

    リダイレクトとは、ブラウザでとあるURLにアクセスしたら、自動的に別のURLに遷移する仕組みのことですが、実際には以下のような手順を踏んでいます。

    1. ブラウザからサーバーに、「○○にアクセスしたいです」というリクエストを送信する
    2. サーバーからブラウザに、「別の場所△△にアクセスしてください」というレスポンスを送信する
    3. ブラウザからサーバーに、「△△にアクセスしたいです」というリクエストを送信する

    redirect_toを使用すると、上記手順の2番目に相当する部分を実装できます。

    (3)headを呼び出し、HTTPヘッダーのみで構成されたレスポンスを作成してブラウザに送信する

    サーバーからのレスポンスであるHTTPメッセージには、HTTPヘッダーとHTTPボディが含まれます。ブラウザは、HTTPボディの内容を用いて画面への表示を行いますが、HTTPヘッダーにある情報(この画面キャッシュをいつまで有効にするのかなど)も利用しています。そして、HTTPヘッダーのみからなるHTTPメッセージも存在します。

    RailsではHTTPヘッダーを適切に設定してくれますが、もちろん独自に設定することもできます。headを使用すると、これを実装できます(render :nothingでも同じようなことができますが、ガイドによるとheadを利用したほうが好ましいようです)。

    レイアウトを構成する

    これまでに習ったヘルパー、yield、content_for、パーシャルを上手に使って構成していく方法が書かれています。個人的には、ヘッダーやフッターなどの画面構成に関わるものはパーシャルで、個別のページで文言を変えたいという要望などにはcontent_forがいいのではないかと思いました。

    Action View フォームヘルパー

    ヘルパーはたくさんあるので、使っていくうちに覚えて慣れていくと思います。まずはform関係から覚えることになるでしょう。

    最後に

    いかがでしたか? 最後の方は決して端折ったのではありません(笑)。後半はさまざまな機能の解説になっているので、今すぐすべてを理解する必要はないと思ったのです。基本的なことを覚えておけば、あとは実装しながら順に慣れていけるでしょう。それではまた!

  • 1983年生まれ。大学卒業後、ソフトウェア開発の営業を経て、ソフトウェア開発業務に転向。現在は自社パッケージのフロントエンド開発のほか、PHPでの受託開発案件、日→英のローカライズ案件などを担当。

    連載バックナンバー

    Think ITメルマガ会員登録受付中

    Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

    Think ITメルマガ会員のサービス内容を見る

    他にもこの記事が読まれています