Ruby on Rails チュートリアル

実例を使ってRailsを学ぼう

Michael Hartl (マイケル・ハートル)

第3版 目次

前書き

私が前にいた会社 (CD Baby) は、かなり早い段階でRuby on Railsに乗り換えたのですが、またPHPに戻ってしまいました (詳細は私の名前をGoogleで検索してみてください)。そんな私ですが、Michael Hartl 氏の本を強く勧められたので、その本を使ってもう一度試してみた結果、今度は無事に Rails に乗り換えることができました。それがこの Ruby on Rails チュートリアルという本です。

私は多くの Rails 関連の本を参考にしてきましたが、真の決定版と呼べるものは本書をおいて他にありません。本書では、あらゆる手順が Rails 流で行われています。最初のうちは慣れるまでに時間がかかりましたが、この本を終えた今、ついにこれこそが自然な方式だと感じられるまでになりました。また、本書は Rails 関連の本の中で唯一、多くのプロが推奨するテスト駆動開発 (TDD: Test Driven Development) を、全編を通して実践しています。実例を使ってここまで分かりやすく解説された本は、本書が初めてでしょう。極めつけは、Git や GitHub、Heroku の実例に含めている点です。このような、実際の開発現場で使わているツールもチュートリアルに含まれているため、読者は、まるで実際のプロジェクトの開発プロセスを体験しているかのような感覚が得られるはずです。それでいて、それぞれの実例が独立したセクションになっているのではなく、そのどれもがチュートリアルの内容と見事に一体化しています。

本書は、筋道だった一本道の物語のようになっています。私自身、章の終わりにある練習問題もやりながら、この Rails チュートリアルを3日間かけて一気に読破しました1。最初から最後まで、途中を飛ばさずにやるのが一番効果的で有益な読み方です。ぜひやってみてください。

それでは、楽しんでお読みください!

Derek Sivers (sivers.org) CD Baby 創業者

謝辞

Ruby on Rails チュートリアルは、私の以前の著書「RailsSpace」と、その時の共著者の Aurelius Prochazka から多くのことを参考にさせてもらっています。Aure には、RailsSpace での協力と本書への支援も含め、感謝したいと思います。また、RailsSpaceRails チュートリアルの両方の編集を担当して頂いた Debra Williams Cauley 氏にも謝意を表したく思います。彼女が野球の試合に連れて行ってくれる限り、私は本を書き続けるでしょう。

私にインスピレーションと知識を与えてくれた Rubyist の方々にも感謝したいと思います: David Heinemeier Hansson、Yehuda Katz、Carl Lerche、Jeremy Kemper、Xavier Noria、Ryan Bat、Geoffrey Grosenbach、Peter Cooper、Matt Aimonetti、Mark Bates、Gregg Pollack、Wayne E. Seguin、Amy Hoy, Dave Chelimsky、Pat Maddox、Tom Preston-Werner、Chris Wanstrath、Chad Fowler、Josh Susser、Obie Fernandez、Ian McFarland、Steven Bristol、Pratik Naik、Sarah Mei、Sarah Allen、Wolfram Arnold、Alex Chaffee、Giles Bowkett、Evan Dorn、Long Nguyen、James Lindenbaum、Adam Wiggins、Tikhon Bernstam、Ron Evans、Wyatt Greene、Miles Forrest、Pivotal Labs の方々、Heroku の方々、thoughtbot の方々、そして GitHub の方々、ありがとうございました。最後に、ここに書ききれないほど多くの読者からバグ報告や提案を頂きました。ご協力いただいた皆様のおかげで、本書の完成度をとことんまで高めることができました。

著者

マイケルハートル (Michael Hartl) は「Ruby on Rails チュートリアル」という Web 開発を始めるときに最もよく参考にされる本の著者です。また、Softcover という自費出版プラットフォームの共同創業者でもあります。以前は、(今ではすっかり古くなってしまいましたが)「RailsSpace」という本の執筆および開発に携わったり、また、 一時人気を博した Ruby on Rails ベースのソーシャルネットワーキングプラットフォーム「Insoshi」の開発にも携わっていました。なお、2011年には、Rails コミュニティへの高い貢献が認められて、Ruby Hero Award を受賞しました。ハーバード大学卒業後、カリフォルニア工科大学物理学博士号を取得し、起業プログラム Y Combinator の卒業生でもあります。

  1. 3日間で読破するのは異常です! 実際にはもっと時間をかけて読むのが一般的です。

第5章 レイアウトを作成する

4の簡単なRubyツアーの中で、サンプルアプリケーション (4.1) にアプリケーションスタイルシートを含める方法を学びました。しかし、4.3.4で指摘したとおり、このスタイルシートは空のままです。この章では、アプリケーションにBootstrapフレームワークを組み込み、そして、カスタムスタイルを追加します1。また、これまで作成したページ (HomeやAboutなど) へのリンクをレイアウトに追加します (5.1)。その途中で、パーシャル、Railsのルーティング、Asset Pipelineについて学び、さらにSassについても紹介します(5.2)。章の最後に、ユーザーをサイトにログインさせるための重要な一歩を踏み出します (5.4)。

本章では、サンプルアプリケーションにレイアウトを追加したり、修正したりといった部分に注力していきます。また、レイアウトについてはテスト駆動開発で進めたり、全くテストを書かない箇所もでてきます。テストを書くときと書かないときのガイドラインについては、コラム3.3で解説します。この結果、本章ではテキストエディタによる修正とブラウザによる確認がほとんどになります。テスト駆動開発で進める唯一の箇所は、5.3.1のContactページの追加する箇所のみです。最後に、新しいテスト手法「 統合テスト (Integration Test)」について紹介します (5.3.4)。統合テストを使って、最終的なレイアウトやリンクが正しいかどうかをチェックします。

5.1 構造を追加する

RailsチュートリアルはWeb開発のための本であり、Webデザインの本ではありませんが、だからといって何のスタイルもない寒々しい外観のアプリケーションでいつまでも作業を続けていると憂鬱になってしまいます。そこで、この章ではレイアウトにいくつかの構造とCSSを与えて最小限のスタイルを追加します。カスタムCSSルールの他に、Twitter社によるオープンソースのWebデザインフレームワークであるBootstrapを利用します。また、コードそのものにもスタイルを与えます。つまり、散らかりはじめたコードレイアウトをパーシャルを使用して整えるということです。

Webアプリケーションを作成するときに、ユーザーインターフェイスの概要をできるだけ早いうちに把握しておくことがしばしば有用です。本書の残りでは、モックアップ (Webの文脈ではよく ワイヤーフレームと呼ばれます) という、最終的なアプリケーションの外観を示す一種のラフスケッチを使用することにします2。この章では、 主に3.2で紹介したサイトロゴ、ナビゲーションヘッダー、サイトフッターを含む静的ページを開発します。これらのページの中で最も重要な、Homeページのモックアップを5.1に示します。モックアップに基いて作成した最終結果は5.7で確認することができます。両者を見比べると、細部が若干異なることに気が付くでしょう (たとえば、実際には最後にRailsのロゴをページに追加します)。しかしモックアップは正確である必要はありませんので、これで十分です。

images/figures/home_page_mockup_3rd_edition
図5.1 サンプルアプリケーションのHomeページのモックアップ

Gitでバージョン管理をしているのであれば、これまでと同様、この時点で新しいブランチを作成するのがよいでしょう。

$ git checkout master
$ git checkout -b filling-in-layout

5.1.1 ナビゲーション

第一段階として、サンプルアプリケーションにリンクとスタイルを追加するために、サイトのレイアウトファイルapplication.html.erb (リスト4.3で登場) にHTML構造を追加し、レイアウトファイルを更新します。この更新には、領域 (divタグ) の追加、CSSクラスの追加、サイトナビゲーションの起点となる領域の追加も含まれます。完全なファイルをリスト5.1に示します。続いて、これを構成している多くの部品について解説します。表示結果を今すぐ確認したいのであれば、5.2で確認できます(注:この時点ではわざわざ見に行くほどの仕上がりではありませんが)。

リスト5.1: 構造を追加したWebサイトのレイアウト app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= stylesheet_link_tag 'application', media: 'all',
                                           'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>
    <!--[if lt IE 9]>
      <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
      </script>
    <![endif]-->
  </head>
  <body>
    <header class="navbar navbar-fixed-top navbar-inverse">
      <div class="container">
        <%= link_to "sample app", '#', id: "logo" %>
        <nav>
          <ul class="nav navbar-nav navbar-right">
            <li><%= link_to "Home",   '#' %></li>
            <li><%= link_to "Help",   '#' %></li>
            <li><%= link_to "Log in", '#' %></li>
          </ul>
        </nav>
      </div>
    </header>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>

それでは、リスト5.1の新しい要素を上から順に見ていきましょう。3.4.1でも簡単に説明しましたが、RailsはデフォルトでHTML5を使用します (<!DOCTYPE html>というdoctypeでそのことが示されています)。HTML5は比較的新しく、一部のブラウザ (特に旧式のInternet Explorer) ではHTML5のサポートが不完全であるため、以下のようなJavaScriptコード (通称 “HTML5 shim”)3 を使用してこの問題を回避します。

<!--[if lt IE 9]>
  <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
  </script>
<![endif]-->

上のコードには、以下のような奇妙な構文が含まれています。

<!--[if lt IE 9]>

これは、Microsoft Internet Explorer (IE) のバージョンが9より小さい場合 (if lt IE 9) にのみ、囲まれている行を実行します。この風変わりな文法 [if lt IE 9] は、Railsの一部ではありません。これは実は、条件付きコメントと呼ばれるもので、今回のような状況のためにInternet Explorerで特別にサポートされています。これにより、Firefox、Chrome、Safariなどの他のブラウザに影響を与えずに、IEのバージョンが9未満の場合にのみHTML5 shimをインクルードすることができるため、非常に好都合です。

それに続くセクションには、サイトのロゴを表示するheader、(divタグによる) いくつかの領域、ナビゲーションリンクのリストがあります。

<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", '#', id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home",   '#' %></li>
        <li><%= link_to "Help",   '#' %></li>
        <li><%= link_to "Log in", '#' %></li>
      </ul>
    </nav>
  </div>
</header>

headerタグは、ページのトップに来るべき要素を表します。このheaderタグには、navbarnavbar-fixed-topnavbar-inverseという3つのCSSクラス3がスペース区切りで与えられています。

<header class="navbar navbar-fixed-top navbar-inverse">

すべてのHTML要素には、クラスとidの両方を指定することができます。これらは単なるラベルで、CSSでスタイルを指定するときに便利です (5.1.2)。クラスとIDの主な違いは、クラスはページの中で何度でも使用できるのに対し、IDは一度しか使用することができない点です。今回の場合、すべてのnavbarクラスには、5.1.2でインストールするBootstrapフレームワークによって特別な意味が与えられます。

headerタグの内側には2つのdivタグがあります。

<div class="container">

divタグは一般的な表示領域を表し、ドキュメントを別々のパーツに分ける以外のことはしません。古いスタイルのHTMLでは、divタグはサイトのほぼすべての領域に使用されますが、HTML5では多くのアプリケーションに共通の領域で使用するheader要素、nav要素、section要素が追加されています。この場合、divタグにもCSSクラス (container) が与えられています。headerタグのクラスと同様に、このクラスもBootstrapにおいて特別な意味を持っています。

divに続いて、埋め込みRubyコードが出現します。

<%= link_to "sample app", '#', id: "logo" %>
<nav>
  <ul class="nav navbar-nav navbar-right">
    <li><%= link_to "Home",   '#' %></li>
    <li><%= link_to "Help",   '#' %></li>
    <li><%= link_to "Log in", '#' %></li>
  </ul>
</nav>

ここでは、リンク (3.3.2で、アンカータグaを使用して作成) を生成するために、Railsヘルパーのlink_toを使用しています。link_toの第1引数はリンクテキスト、第2引数はURLです。このURIは5.3.3名前付きルートのURLに変更しますが、今はWebデザインで一般に使用されるスタブURI’#’にしておきます。第3引数はオプションハッシュで、この場合はサンプルアプリのリンクでCSSのid logoを指定しています(他の3つのリンクにはオプションハッシュが指定されていませんが、必須ではないので構いません)。Railsヘルパーは、このようにオプションのハッシュを取ることがよくあり、これによりRailsのコードから離れることなく任意のHTMLオプションを柔軟に追加することができます。

divの内側の2番目の要素は、リストアイテムタグli順不同リストタグulによって作られた、ナビゲーションリンクのリストです。

<nav>
  <ul class="nav navbar-nav navbar-right">
    <li><%= link_to "Home",   '#' %></li>
    <li><%= link_to "Help",   '#' %></li>
    <li><%= link_to "Log in", '#' %></li>
  </ul>
</nav>

正確にはここでは不要なのですが、navタグには「その内側がナビゲーションリンクである」という意図を明示的に伝える役割があります。さらに、ulタグに付与されているnavnavbar-navnavbar-rightクラスもBootstrapにおいて特別な意味を持ちます。したがって、5.1.2でBootstrapのCSSを追加したときに、これらのスタイルも自動的に適用されます。ブラウザからソースを見ることで確認ができますが、Railsが埋め込みRubyを評価し、レイアウトを描画すると、上のリストは以下のように置き換わります5

<nav>
  <ul class="nav navbar-nav navbar-right">
    <li><a href="#">Home</a></li>
    <li><a href="#">Help</a></li>
    <li><a href="#">Log in</a></li>
  </ul>
</nav>

これがブラウザに返されるHTMLになります。

レイアウトの最後の部分は、メインコンテンツ用のdivです。

<div class="container">
  <%= yield %>
</div>

上と同様、containerクラスもBootstrapにおいて特別な意味を持ちます。3.4.3で学んだように、yieldメソッドはWebサイトのレイアウトにページごとの内容を挿入します。

5.1.3で追加するサイトフッターを除いて、これでレイアウトは完成しました。Homeページへアクセスして表示結果を確認することができます。今後登場するスタイル要素を利用できるようにするために、home.html.erbビューに特別な要素をいくつか追加します(リスト5.2)。

リスト5.2: サインアップページへのリンクがあるHomeページ app/views/static_pages/home.html.erb
<div class="center jumbotron">
  <h1>Welcome to the Sample App</h1>

  <h2>
    This is the home page for the
    <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
    sample application.
  </h2>

  <%= link_to "Sign up now!", '#', class: "btn btn-lg btn-primary" %>
</div>

<%= link_to image_tag("rails.png", alt: "Rails logo"),
            'http://rubyonrails.org/' %>

第7章でサイトにユーザーを追加するときに備えて、最初のlink_toに仮のリンクを作成します。

<a href="#" class="btn btn-lg btn-primary">Sign up now!</a>

上で挙げたdivタグのCSSクラスjumbotronや、signupボタンのbtnクラス、btn-lgクラス、btn-primaryクラスはすべて、Bootstrapにおいて特別な意味を持ちます。

2番目のlink_toでは、引数として画像ファイルのパスと任意のオプションハッシュをとるimage_tagヘルパーの能力が示されています。シンボルを使用して、この場合はalt属性を設定しています。画像を表示するためには、rails.pngというRailsのロゴ画像ファイルを加える必要があります。Ruby on Rails公式ページの http://railstutorial.jp/rails.png から画像をダウンロードして、app/assets/images/ディレクトリに置いてください。Cloud IDEやUnix系のOS (Max OS Xなど) を使っている場合は、次のようにcurlコマンドで簡単に取得できます6

$ curl -OL http://railstutorial.jp/rails.png
$ mv rails.png app/assets/images/

Cloud IDEを使っていると、(筆者にも理由は分からないのですが) ときどき2行目のmvコマンドで失敗することがあるようです。その場合は、1行目のcurlコマンドをもう一度実行して、ロゴ画像が正しくダウンロードできているかどうか確認してください (curlコマンドの詳細については、Conquering the Command Lineという本の第3章 (英語) を参照してください) 。リスト5.2image_tagヘルパーを使っているので、Railsは該当する画像ファイルを、アセットパイプラインを通してapp/assets/images/ディレクトリの中から探してくれます (アセットパイプラインについては5.2で説明します)。

image_tagの効果を確かめるために、ブラウザから生成されたHTMLを見てみましょう7

<img alt="Rails logo" src="/assets/rails-9308b8f92fea4c19a3a0d8385b494526.png" />

ファイル名が重ならないようにするために、Railsが9308b8f92fea4c19a3a0d8385b494526という文字列 (実際の文字列はシステムごとに異なります) を追加していることがわかります。これは、たとえば画像ファイルを新しい画像に更新したときに、ブラウザ内に保存されたキャッシュに意図的にヒットさせないようにするための仕組みです。また、src属性には "images" というディレクトリ名が含まれていないことにも注目してください。これはassetsディレクトリ内の他のディレクトリ (imagesやjavascripts、stylesheetsなど) も同様です。これは高速化のための仕組みで、Railsはassetsディレクトリ直下の画像をapp/assets/imagesディレクトリにある画像と紐付けています。これにより、ブラウザから見るとすべてのファイルが同じディレクトリにあるように見えるようになります。そして、このようなフラットなディレクトリ構成を採っていると、ファイルをより高速にブラウザに渡すことができるようになります。最後に、alt属性は、画像がない場合に代わりに表示される文字列です。たとえば視覚障害のあるユーザーが使用するスクリーンリーダーでは、ここの属性が読み上げられて、そこに画像があることが示されます。

いよいよ、ここまでの苦労の成果を確認する準備ができました (5.2)。思っていたよりもみすぼらしいでしょうか。そうかもしれません。しかし、HTML要素に実用的なクラスを与えるという良い仕事ができたのも確かです。さらに、クラスを与えたこの段階で、CSSを使用してサイトにスタイルを与えることができたのは、タイミングとして非常に適切であると思います。

images/figures/layout_no_logo_or_custom_css_bootstrap_3rd_edition
図5.2 カスタムCSSを使用していないHomeページ

5.1.2 BootstrapとカスタムCSS

5.1.1では、多くのHTML要素にCSSクラスを関連付けました。こうしておくことで、CSSベースでレイアウトを構成する際に高い柔軟性を与えてくれます。5.1.1で述べたように、これらのクラスの多くは、Twitterが作成したフレームワークであるBootstrap特有のものです。Bootstrapを使用すると、洗練されたWebデザインとユーザーインターフェイス要素を簡単にHTML5アプリケーションに追加することができます。この節では、サンプルアプリケーションにスタイルを追加するために、カスタムCSSルールとBootstrapを組み合わせて使用します。注目すべき点は、Bootstrapを使うことでアプリケーションをレシポンシブデザインにできるということです。これにより、どの端末でアプリケーションを閲覧しても、ある程度見栄えをよくすることができます。

最初に、リスト5.3で示しているようにBootstrapを追加しましょう。これは、bootstrap-sass gemを使用してRailsアプリケーションに導入できます。Bootstrapフレームワークでは、動的なスタイルシートを生成するためにLESS CSS言語を使用していますが、RailsのAsset Pipelineはデフォルトでは (LESSと非常によく似た) Sass言語をサポートします (5.2)。そのため、bootstrap-sassは、LESSをSassへ変換し、必要なBootstrapファイルを現在のアプリケーションですべて利用できるようにします8

リスト5.3: Gemfilebootstrap-sassを追加する
source 'https://rubygems.org'

gem 'rails',                '4.2.2'
gem 'bootstrap-sass',       '3.2.0.0'
.
.
.

いつものようにbundle installを実行して、Bootstrapをインストールします。

$ bundle install

ちなみに、rails generateコマンドを実行することでコントローラーごとに分けられたCSSファイルが自動的に生成されますが、これらのファイルを正しい順序で読み込ませるのは至難の技なので、本チュートリアルでは (簡潔のために) すべてのCSSを1つにまとめる方針を採っています。カスタムCSSを動かすための最初の一歩は、カスタムCSSファイルを作ることです。

$ touch app/assets/stylesheets/custom.css.scss

(ここでは3.3.3の途中で紹介したtouchコマンドを使っていますが、ファイルが作成できるなら [新規ファイル作成] や他のコマンドでも問題ありません。) このディレクトリ名とファイル名は、どちらも重要です。以下のディレクトリは、

app/assets/stylesheets/

Asset Pipeline (5.2)の一部であり、このディレクトリに置かれたスタイルシートはapplication.cssの一部として自動的にWebサイトのレイアウトにインクルードされます。さらに、ファイル名のcustom.css.scssには.cssという拡張子も含まれているので、このファイルはCSSファイルであることが示されています。また、.scssという拡張子も含まれているので、 このファイルはSassを記述できるCSSファイル (Sassy CSS: Scss) であることも示されており、Asset Pipelineはこれを見てSassを処理できるようにします(Sassは5.2.2まで登場しませんが、bootstrap-sass gemが動作するためのおまじないとして必要です)。

カスタムCSS用のファイルを作成したら、リスト5.4のように@importを使用して、Bootstrap (とそれに関連するSprockets) をインクルードします9

リスト5.4: Bootstrap CSSを追加する app/assets/stylesheets/custom.css.scss
@import "bootstrap-sprockets";
@import "bootstrap";

リスト5.4の2行では、Bootstrap CSSのフレームワークを導入しています。導入後、Webサーバを再起動させると、アプリケーションに反映させることができます (1.3.2で紹介したように、Ctrl-Cを押してWebサーバを停止させた後、rails serverコマンドを打ってWebサーバを起動してください)。うまくいけば5.3のような結果になります。さて、テキストの配置は今ひとつで、ロゴにはスタイルもありませんが、色使いとsignupボタンはなかなかよい感じになってきました。

images/figures/sample_app_only_bootstrap_3rd_edition
図5.3 Bootstrap CSSとサンプルアプリケーション

次に、リスト5.5に示したように、Webサイト全体にわたってレイアウトと個別のページにスタイルを与えるためのCSSを追加します。テストの結果を5.4に示します。リスト5.5には多数の記述ルールがあります。CSSの記述ルールを把握するためには、関心のある箇所をコメントアウトして表示を確認することをお勧めします。CSSでは、/* … */でコメントアウトできるので、調べてみたいコードをこれで囲い、表示がどのように変わるかを確認してみてください。

リスト5.5: すべてのページに適用される共通のスタイルをCSSに追加する app/assets/stylesheets/custom.css.scss
@import "bootstrap-sprockets";
@import "bootstrap";

/* universal */

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

.center {
  text-align: center;
}

.center h1 {
  margin-bottom: 10px;
}
images/figures/sample_app_universal_3rd_edition
図5.4 スペースや共通スタイルを追加した結果

リスト5.5のCSSの形式は一貫しています。CSSルールでは一般に、クラス、id、HTMLタグ、またはそれらの組み合わせ、のいずれかを指定します。そしてその後ろにスタイリングコマンドのリストを記述します。たとえば、以下のコードでは、

body {
  padding-top: 60px;
}

ページ上部に60ピクセルの余白を追加します。headerタグにnavbar-fixed-topクラスが与えられているので、これに従ってBootstrapはナビゲーションバーをページ上部に固定し、ナビゲーションバーの下に余白を置いて主要部分から分離します(デフォルトのnavbarの色がBootstrap 2.0から変更されたため、現在の淡色の代わりにダークな色調にしたい場合はnavbar-inverseクラスを使用する必要があります)。また、このルールにある以下のCSSは、

.center {
  text-align: center;
}

centerクラスにtext-align: centerプロパティを関連付けています。言い換えると、.center冒頭のドット.は、このルールがクラスに対してスタイルを適用することを示しています。(冒頭がポンド記号#の場合は、リスト5.7に示したように、そのルールがCSSのidに対してスタイルを適用することを示します。この場合、centerクラスに属している (divなどの) タグの内側にある要素は、すべてページ中でセンタリングされることを意味しています(このクラスの例はリスト5.2で参照できます)。

Bootstrapには洗練されたタイポグラフィーを利用できるCSSルールがありますが、ここではさらに、リスト5.6に示したようにサイトのテキストの外観を変えるカスタムCSSルールを追加しましょう。(これらのルールはHomeページですべて適用されるとは限りませんが、サンプルアプリケーションの他の場所でも使用されるものもあります)。リスト5.6を反映した結果を5.5で確認することができます。

リスト5.6: 洗練されたタイポグラフィーを利用するためのCSSを追加する app/assets/stylesheets/custom.css.scss
@import "bootstrap-sprockets";
@import "bootstrap";
.
.
.
/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: #777;
}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}
images/figures/sample_app_typography_3rd_edition
図5.5: タイポグラフィースタイルを追加する

最後に、いくつかのルールをサイトロゴに追加します。このサイトロゴは「sample app」だけが表示されているシンプルなものです。リスト5.7のCSSは、テキストを大文字に変換し、サイズ、色、配置を変更します(サイトロゴがページで一度しか使用されないことを前提としてCSS idを使用していますが、代わりにクラスを使用することもできます)。

リスト5.7: サイトロゴにCSSを追加する app/assets/stylesheets/custom.css.scss
@import "bootstrap-sprockets";
@import "bootstrap";
.
.
.
/* header */

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
}

#logo:hover {
  color: #fff;
  text-decoration: none;
}

上のコードのcolor: #fffは、ロゴの色を白に変更します。HTMLの色は、16進数 (基数が16) の3つの数値の組み合わせで表現され、赤、緑、青の三原色に (この順序で) コード化することができます。このコード#ffffffは、3色すべてが最大に使用されており、純白になります。なお、#fffは、完全な#ffffffの短縮形です。CSS標準には、共通HTMLカラーの別名も多数定義されています。たとえば、#fffwhiteと書くこともできます。リスト5.7のCSSの結果は5.6で確認できます。

5.1.3 パーシャル (partial)

リスト5.1のレイアウトはその目的を果たしていますが、少々散らかっています。HTML shimは、それだけで3行も占有し、風変わりなIE特有の文法を使用しているので、これをうまく隠すことができたらどんなによいでしょう。また、HTMLヘッダーは論理的な単位を形成するため、一箇所にまとめる必要もあります。Railsでは、パーシャル (partial) と呼ばれる機能を使用してこれを実現することができます。最初に、パーシャルを定義するとレイアウトがどのように変わるかを見てみましょう (リスト5.8)。

リスト5.8: レイアウトにshimとheaderのパーシャルを追加する app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= stylesheet_link_tag 'application', media: 'all',
                                           'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>

リスト5.8では、以下のようにrenderと呼ばれるRailsヘルパー呼び出しだけを使って、HTML shimのスタイルシート行を置換しています。

<%= render 'layouts/shim' %>

この行では、app/views/layouts/_shim.html.erbというファイルを探してその内容を評価し、結果をビューに挿入しています10 (<%= ... %>は、テンプレート内でRubyの式を評価するための埋め込みRuby記法であることを思い出してください。評価した結果がテンプレートに挿入されます)。ファイル名_shim.html.erbの前のアンダースコアに注目してください。このアンダースコアは、パーシャルで使用する普遍的な命名規約であり、また、一目見ただけでディレクトリ中のすべてのパーシャルを識別することが可能になります。

もちろん、パーシャルが動作するためには、それに対応するファイルとコンテンツを記述しなければなりません。このshimパーシャルの場合は、リスト5.1のわずか3行のshimコードだけです。追加した結果をリスト5.9に示します

リスト5.9: HTML shim用のパーシャル app/views/layouts/_shim.html.erb
<!--[if lt IE 9]>
  <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
  </script>
<![endif]-->

同様に、他のヘッダーの情報もリスト5.10のパーシャルに移動し、renderを呼び出してレイアウトに挿入することができます。(パーシャルでは、自動生成せずに、テキストエディタを使って手動で作成するのが一般的です。)

リスト5.10: header用のパーシャル app/views/layouts/_header.html.erb
<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", '#', id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home",   '#' %></li>
        <li><%= link_to "Help",   '#' %></li>
        <li><%= link_to "Log in", '#' %></li>
      </ul>
    </nav>
  </div>
</header>

これでパーシャルの作成方法がわかりましたので、今度はヘッダーに対応するフッターを同じ方法で追加しましょう。ここまでくれば、ファイル名は_footer.html.erbで、layoutsディレクトリ (リスト5.11) に置けばよいということがわかると思います11

ヘッダーの場合と同様に、フッターの中でもlink_toメソッドを使用して、AboutページとContactページへの内部リンクを追加してあります。ひとまず、リンク先のURLは’#’としておきます(headerタグと同様、footerタグもHTML5で新たに追加された要素です)。

フッタパーシャルは、スタイルシートやヘッダーパーシャルのときと同じ方法でレイアウト中に追加できます (リスト5.12)。

そのまま実際にフッターを表示してみるとどうにも見苦しいので、リスト5.13でスタイルを若干追加しましょう。スタイルを追加した結果を5.7に示します。

5.2 SassとAsset Pipeline

最近のRailsに追加された機能の中で最も特筆すべき機能のひとつは、CSS、JavaScript、画像などの静的コンテンツの生産性と管理を大幅に強化する「Asset Pipeline」です。この節では、Asset Pipelineの概要と、素晴らしいCSS生成ツールである「Sass」の使い方について説明します。

5.2.1 Asset Pipeline

アセットパイプラインは、Railsの流儀を守りながら多大な変化をもたらしますが、一般的なRails開発者の視点からは、アセットディレクトリ、マニフェストファイル、プリプロセッサエンジンという、3つの主要な機能が理解の対象となります12。では、それぞれを順に見ていきましょう。

アセットディレクトリ

Rails 3.0以前のバージョンでは、静的ファイルはpublic/以下の次のディレクトリに置かれていました。

  • public/stylesheets
  • public/javascripts
  • public/images

これらのディレクトリ中のファイルは http://example.com/stylesheets のようなリクエストによって自動的に配信されます。これは3.0以降も同様です。

Rails3.1以降では、静的ファイルを目的別に分類する、標準的な3つのディレクトリが使用されるようになりました。最新のRailsでも同様です。

  • app/assets: 現在のアプリケーション固有のアセット
  • lib/assets: あなたの開発チームによって作成されたライブラリ用のアセット
  • vendor/assets: サードパーティのアセット

これらのディレクトリには、それぞれのアセットクラス用のサブディレクトリがあります。たとえば、app/assetsには次のようなサブディレクトリがあります。

$ ls app/assets/
images/  javascripts/  stylesheets/

上記の説明から、5.1.2で取り上げたカスタムCSSが配置された場所と、その理由について理解することができると思います。custom.css.scssは、サンプルアプリケーション固有のアセットなので、app/assets/stylesheetsに配置されているのです。

マニフェストファイル

アセットを上記の論理的な場所へ配置すれば、マニフェストファイルを使用して、それらをどのように1つのファイルにまとめるのかをRailsに指示することができます。なお、実際にまとめるのはSprockets gemが行います。(マニフェストファイルはCSSとJavaScriptには適用されますが、画像ファイルには適用されません) 。1つの例として、アプリケーションスタイルシート用のマニフェストファイルを見てみましょう (リスト5.14)。

リスト5.14: アプリケーション固有のCSS用マニフェストファイル app/assets/stylesheets/application.css
/*
 * This is a manifest file that'll be compiled into application.css, which
 * will include all the files listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets,
 * vendor/assets/stylesheets, or vendor/assets/stylesheets of plugins, if any,
 * can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear
 * at the bottom of the compiled file so the styles you add here take
 * precedence over styles defined in any styles defined in the other CSS/SCSS
 * files in this directory. It is generally better to create a new file per
 * style scope.
 *
 *= require_tree .
 *= require_self
 */

上の行で重要な部分は実はCSSコメントの中にあります。以下の行は、適切なファイルをインクルードするためにSprocketsによって使用されます。

/*
 .
 .
 .
 *= require_tree .
 *= require_self
*/

以下の行は、

*= require_tree .

app/assets/stylesheetsディレクトリ (サブディレクトリを含む) 中のすべてのCSSファイルが、アプリケーションCSSに含まれるようにします。次の行

*= require_self

CSSの読み込みシーケンスの中で、application.css自身もインクルードすることを指定しています。

Railsには実用的なデフォルトのマニフェストファイルが付属しているので、Railsチュートリアルでは変更を加える必要がありませんが、もし必要な場合は、Railsガイドの「アセットパイプライン」で詳細な情報を参照できます。

プリプロセッサエンジン

必要なアセットをディレクトリに配置してまとめた後、Railsはさまざまなプリプロセッサエンジンを介してそれらを実行し、ブラウザに配信できるようにそれらをマニフェストファイルを用いて結合し、サイトテンプレート用に準備します。Railsは、どのプリプロセッサを使用するかを、ファイル名の拡張子を使用して判断します。最も一般的な拡張子は、Sass用の.scss、CoffeeScript用の.coffee、埋め込みRuby (ERb) 用の.erbです。3.4.3では最初にERbを、5.2.2ではSassをそれぞれ扱いました。なお本書では扱いませんが、CoffeeScriptはエレガントで簡潔な言語で、JavaScriptにコンパイルして実行します(興味のある方は、RailsCastの「CoffeeScriptの基礎 (英語)」から始めると良いでしょう)。

プリプロセッサエンジンはつなげて実行する (chain) ことができます。

foobar.js.coffee

上の拡張子の場合、CoffeeScriptプロセッサ経由で実行されます。

foobar.js.erb.coffee

上の拡張子の場合は、CoffeeScriptとERbの両方で実行されます (コードは右から左へと実行されますので、この例ではCoffeeScriptが最初に実行されます)。

本番環境での効率性

Asset Pipelineの最大のメリットの1つは、本番のアプリケーションで効率的になるように最適化されたアセットも自動的に生成されることです。従来は、CSSとJavaScriptを整理するために、機能を個別のファイルに分割し、(インデントを多用して) 読みやすいフォーマットに整えていました。これは、プログラマにとっては便利な方法ですが、本番環境にとっては非効率です。それというのも、最小化されていないCSSやJavaScriptファイルを多数インクルードすると、ページの読み込み時間が著しく遅くなるからです (読み込み時間は、ユーザー体験の質に影響を与える重要な指標の1つです)。Asset Pipelineを使うと、この「開発効率と読み込み時間のどちらを重視するか」という問題について悩む必要がなくなります。開発環境ではプログラマにとって読みやすいように整理しておき、本番環境ではAsset Pipelineを使ってファイルを最小化すればよいのです。具体的には、Asset Pipelineがすべてのスタイルシートを1つのCSSファイル (application.css) にまとめ、すべてのJavaScriptファイルを1つのJSファイル (javascripts.js) にまとめてくれます。さらに、それらのファイルすべてに対して 不要な空白やインデントを取り除く処理を行い、ファイルサイズを最小化してくれます。結果として、開発環境と本番環境という、2つの異なった状況に対してそれぞれ最高の環境を提供してくれます。

5.2.2 素晴らしい構文を備えたスタイルシート

Sass は、スタイルシートを記述するための言語であり、CSSに比べて多くの点が強化されています。この節では、Sassが提供する2つの重要な機能、ネスト変数について説明します。(3つ目の重要な機能であるミックスインについては、7.1.1で紹介します)。

5.1.2でも簡単に説明しましたが、SassはSCSSというフォーマットに対応しています (.scssという拡張子はSCSSであることを表します)。SCSSは、厳密な意味で、CSS本体を抽象化したフォーマットです。具体的には、SCSS は CSS に新しい機能を追加しただけで、全く新しい構文を定義したようなものではありません13。本書の例では、Bootstrapの恩恵を得るために、私達は最初からSCSSを使用しています。RailsのAsset Pipelineは、.scssという拡張子を持つファイルをSassを使って自動的に処理してくれます。このため、custom.css.scssファイルはSassプリプロセッサによって前処理され、その後ブラウザへの配信に備えてパッケージ化されます。

ネスト

スタイルシート内に共通のパターンがある場合は、要素をネストさせることができます。たとえば、リスト5.5では、以下のように.center.center h1の両方に対してルールがあります。

.center {
  text-align: center;
}

.center h1 {
  margin-bottom: 10px;
}

上のルールは、Sassを使用して以下のように書き換えることができます。

.center {
  text-align: center;
  h1 {
    margin-bottom: 10px;
  }
}

上の例では、ネストの内側にあるh1というルールは、.centerのルールを継承しています。

今度は、もう少し異なるルールに対してネスト機能を使う例を見てみましょう。リスト5.7には以下のコードがあります。

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
}

#logo:hover {
  color: #fff;
  text-decoration: none;
}

上のコードには#logoというidが2回使用されています。1回目はロゴ自身を定義するために、2回目はhover属性を定義するために使用されています (なおhover属性は、該当する要素の上にマウスポインタをかざしたときの表示を定義します)。2つ目のルールをネストするためには、親属性である#logoを参照する必要があります。このような場合、SCSSでは以下のようにアンパーサンド&を使って実現できます。

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
  &:hover {
    color: #fff;
    text-decoration: none;
  }
}

Sassは、SCSSをCSSに変換する際に、&:hover#logo:hoverに置換します。

これらのネスト機能は、フッターのCSSでも使用できます。リスト5.13のコードは、SCSSを使用して以下のように書き換えることができます。

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid #eaeaea;
  color: #777;
  a {
    color: #555;
    &:hover {
      color: #222;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 15px;
    }
  }
}

リスト5.13を手作業で変換してみることは、良い演習になります。変換後にもCSSが適切に動作していることを確認してみましょう。

変数

Sassでは、冗長なコードを削除し、より自由な表現を可能にするために、変数が定義できるようになっています。たとえば、リスト5.6リスト5.13を見てみると、同じ色を繰り返し参照している箇所があります。

h2 {
  .
  .
  .
  color: #777;
}
.
.
.
footer {
  .
  .
  .
  color: #777;
}

上のコードの#777は薄い灰色を指しています。Sassでは、このような値を変数として定義し、以下のように変数名を与えることができます。

$light-gray: #777;

この機能を使用して、SCSSを以下のように書き直すことができます。

$light-gray: #777;
.
.
.
h2 {
  .
  .
  .
  color: $light-gray;
}
.
.
.
footer {
  .
  .
  .
  color: $light-gray;
}

$light-grayのような変数名は、#777 のような値よりもわかりやすいので、たとえその変数が繰り返し使われないとしても、変数名を与えることは多くの場合有用です。実際、Bootstrapフレームワークでは、多くの色に対して変数名を定義しています。定義されている変数はBootstrapページの「LESS変数一覧」で参照することができます。このWebサイトでは、SassではなくLESSを使って変数が定義されていますが、bootstrap-sassというgemを使用すれば、Sassでも同様の変数が使えるようになります。LESSとSassの違いを想像するのはそれほど難しくありません。たとえば、LESSではアットマーク@を使用しているのに対して、Sassはドルマーク$を使っていることはすぐにわかります。話を戻して、Bootstrapの変数の一覧表を見ると、薄い灰色に対して以下の変数名が与えられることに気が付きます。

 @gray-light: #777;

これは、bootstrap-sassというgemを使えば、SCSSでも同様に$gray-lightという変数が使えることを意味しています。先ほど定義した$light-grayというカスタム変数の代わりに、用意された変数を使ってみましょう。

h2 {
  .
  .
  .
  color: $gray-light;
}
.
.
.
footer {
  .
  .
  .
  color: $gray-light;
}

今回取り上げたSassのネスト機能や変数機能を使ってSCSSファイルを全面的に書き直すと、リスト5.15のようになります。このリストでは、Sassの変数 (詳しくはBootstrap LESSの変数一覧を参考にしてください) や、組み込みの色変数 (たとえば#fffにはwhite という変数) を使っています。footerタグのルールが、劇的に向上していることを確認してみてください。

リスト5.15: ネストや変数を使って初期のSCSSファイルを書き直した結果 app/assets/stylesheets/custom.css.scss
@import "bootstrap-sprockets";
@import "bootstrap";

/* mixins, variables, etc. */

$gray-medium-light: #eaeaea;

/* universal */

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

.center {
  text-align: center;
  h1 {
    margin-bottom: 10px;
  }
}

/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: $gray-light;
}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}


/* header */

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: white;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
  &:hover {
    color: white;
    text-decoration: none;
  }
}

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $gray-medium-light;
  color: $gray-light;
  a {
    color: $gray;
    &:hover {
      color: $gray-darker;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 15px;
    }
  }
}

Sassを使ってスタイルシートをより簡単にする方法は他にもありますが、今回はその中でも最も重要な機能を使ってリスト5.16を書き直しました。Sassを使うことによって、素晴らしいスタートを切ることができました。Sassの詳細については、Sass の公式サイト (英語) を参照してください。

5.4 ユーザー登録: 最初のステップ

この節では、レイアウトとルーティングの取り組みにおける頂点として、ユーザー登録ページへのルーティングを作成します。そのために2番目のコントローラを作成することになります。これは、Webサイトでユーザー登録を行えるようにするための最初の重要な一歩となります。次の一歩であるユーザーのモデリングは第6章で行い、第7章でユーザー登録が完成します。

5.4.1 Usersコントローラ

3.2で、最初のコントローラであるStaticPagesコントローラを作成しました。今度は2番目のコントローラであるUsersコントローラを作成しましょう。1番目のときと同様、generateを実行して、現時点での要求である新規ユーザー用のユーザー登録ページ (スタブ) を持つ、最も簡単なコントローラを作成します。Railsで好まれているRESTアーキテクチャの規約に従い、新規ユーザー用のアクションをnewとします。したがって、generate controllerの引数にnewを渡して、自動的にアクションを作成してみましょう。変更の結果をリスト5.28に示します。

リスト5.28: Usersコントローラの生成 (newアクションを追加)
$ rails generate controller Users new
      create  app/controllers/users_controller.rb
       route  get 'users/new'
      invoke  erb
      create    app/views/users
      create    app/views/users/new.html.erb
      invoke  test_unit
      create    test/controllers/users_controller_test.rb
      invoke  helper
      create    app/helpers/users_helper.rb
      invoke    test_unit
      create      test/helpers/users_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/users.js.coffee
      invoke    scss
      create      app/assets/stylesheets/users.css.scss

リスト5.28により、newアクションを持つUsersコントローラ(リスト5.30)と、スタブのユーザービューを作成します(リスト5.31)。このとき、新しいUserページ用の小さなテスト (リスト5.32) も生成されていて、この時点ではパスするはずです。

リスト5.29: green
$ bundle exec rake test
リスト5.30: newアクションを持つ最初のUsersコントローラ app/controllers/users_controller.rb
class UsersController < ApplicationController

  def new
  end
end
リスト5.31: Users用の最初のnewアクション app/views/users/new.html.erb
<h1>Users#new</h1>
<p>Find me in app/views/users/new.html.erb</p>
リスト5.32: Userページ用の最初のテスト GREEN test/controllers/users_controller_test.rb
require 'test_helper'

class UsersControllerTest < ActionController::TestCase

  test "should get new" do
    get :new
    assert_response :success
  end
end

5.4.2 ユーザー登録用URL

5.4.1のコードにより、新規ユーザー用の動作するページが/users/new にできました。ここで5.1を思い出していただきたいのですが、URLは/users/newではなく表のとおりに/signupにしたいと思います。リスト5.22の例に従い、ユーザー登録URL用にget ’/signup’のルールを追加します (リスト5.33)。

リスト5.33: ユーザー登録ページのルート config/routes.rb
Rails.application.routes.draw do
  root             'static_pages#home'
  get 'help'    => 'static_pages#help'
  get 'about'   => 'static_pages#about'
  get 'contact' => 'static_pages#contact'
  get 'signup'  => 'users#new'
end

次に、新しく定義された名前付きルートを使って、Homeページのボタンに適切なリンクを追加します。他のルートと同様、get ’/signup’と記述したことでsignup_pathという名前付きルートができ、それをリスト5.34で使用します。signupページへのテストは演習に回すことにします (5.6)。

最後に、signupページ用のカスタムスタブ (stub) のビューを追加します (5.35)。

リスト5.35: 最初のユーザー登録ページ (スタブ) app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<p>This will be a signup page for new users.</p>

これで、少なくともサインインのルートを追加するまでの間、リンクと名前付きルートが完成しました(第8章)。結果を5.9の新規ユーザーのページ (URI /signup) に示します。

images/figures/new_signup_page_3rd_edition
図5.9 /signupで表示される新しいユーザー登録ページ

5.5 最後に

この章では、アプリケーションのレイアウトを形にし、ルーティングを洗練させました。本書では、以後サンプルアプリケーションを肉付けすることに専念します。最初に、ユーザー登録、サインイン、サインアウトできるユーザーを追加します。次に、マイクロポストを追加します。最後に、他のユーザーをフォローできるようにします。

Gitを使っている方は、この時点でmasterブランチに変更をマージしてください。

$ bundle exec rake test
$ git add -A
$ git commit -m "Finish layout and routes"
$ git checkout master
$ git merge filling-in-layout

続いて、Bitbucketにプッシュします。

$ git push

最後に、Herokuへデプロイします。

$ git push heroku

デプロイが無事に終わると、本番環境でサンプルアプリケーションが動いているはずです (5.10)。

images/figures/layout_production
図5.10: 本番環境で動くサンプルアプリケーション

5.5.1 本章のまとめ

  • HTML5を使ってheaderやfooter、logoやbodyといったコンテンツのレイアウトを定義しました
  • Railsのパーシャルは効率化のために使われ、別ファイルにマークアップを切り出すことができます
  • CSSは、CSSクラスとidを使ってレイアウトやデザインを調整します
  • Bootstrapフレームワークを使うと、いい感じのデザインを素早く実装できる
  • SassとAsset Pipelineは、(開発効率のために切り分けられた) CSSの冗長な部分を圧縮し、本番環境に最適化した結果を出力する
  • Railsのルーティングでは自由にルールを定義することができ、また、その際に名前付きルートも使えるようになる
  • 統合テストは、ブラウザによるページ間の遷移を効率的にシミュレートする

5.6 演習

: 『演習の解答マニュアル (英語)』にはRuby on Railsチュートリアルのすべての演習の解答が掲載されており、www.railstutorial.orgから購入して頂いた方は無料で手に入れることができます。

演習とチュートリアル本編の食い違いを避ける方法については、3.6のトピックブランチの演習に追加したメモをご覧ください。

  1. 5.2.2で触れたように、まずはリスト5.13のフッター用CSSをリスト5.15のSCSSに変更してみてください。
  2. リスト5.25の統合テストに、 getメソッドを使ってユーザー登録ページにアクセスし、ページタイトルが正しいかどうかチェックするテストコードを加えてください。
  3. リスト5.36で示すように、Applicationヘルパーで使っているfull_titleヘルパーを、test環境でも使えるようにすると便利です。こうしておくと、リスト5.37のようなコードを使って正しいタイトルをテストすることができます (ちなみにこれは前回の演習の応用でもあります)。ただし、これは完璧なテストではありません。たとえばベースタイトルに“Ruby on Rails Tutoial”といった誤字があったとしても、このテストでは発見することができないでしょう。この問題を解決するためには、full_titleヘルパーに対するテストを書く必要があります。そのために、Applicationヘルパーをテストするファイルを作成し、リスト5.38FILL_INの部分を適切なコードに置き換えてみてください。(ヒント: リスト5.38ではassert_equal <期待される値>, <実際の値>といった形で使っていましたが、内部では==演算子を使って、期待される値と実際の値を比較して正しいかどうかテストしています。)
リスト5.36: テスト環境でもApplicationヘルパーを使えるようにする test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
.
.
.
class ActiveSupport::TestCase
  fixtures :all
  include ApplicationHelper
  .
  .
  .
end
リスト5.38: full_titleヘルパーの単体テスト test/helpers/application_helper_test.rb
require 'test_helper'

class ApplicationHelperTest < ActionView::TestCase
  test "full title helper" do
    assert_equal full_title,         FILL_IN
    assert_equal full_title("Help"), FILL_IN
  end
end
  1. Colm Tuiteの多大な貢献により、サンプルアプリケーションをBootstrap CSSのフレームワークに変換することができました。感謝します。
  2. Ruby on Railsチュートリアル のモックアップは、「Mockingbird」という素晴らしいモックアップ作成サービスで作られています。
  3. shimshivという単語は、今回の用途ではどちらでも大丈夫です。shimを意味は「洗う機械、もしくは薄い物質を整理しフィットさせるためのモノ、あるいは服を削除すること」なので、意味合いとしては前者が正しいです。ちなみに後者は「ナイフ、もしくは武器として使う剃刀」という意味なので、おそらく原著者である Sjoerd Visscherのちょっとしたイタズラ心でしょう。
  4. CSSクラスは、Rubyのクラスとはまったく関係がありません。
  5. スペースを入れると見栄えが変わるかもしれませんが、3.4.1で触れたようにHTMLは重複する空白を無視するのでどちらでも大丈夫です。
  6. もしOS XのHomebrewが使えるようになっていれば、brew install curlというコマンドを打ってcurlをインストールすることができます。 
  7. 既にお気付きだと思いますが、imgタグは<img>...</img>ではなく<img ... />と書きます。この書式に従うタグは閉じタグとして知られています。 
  8. Asset PipelineではLessを使うこともできます。詳しくはless-rails-bootstrap gemを参照してください。
  9. もしこのステップが摩訶不思議に思えたら、次のように考えてみましょう。「私はただbootstrap-sassのREADMEファイルに従っているのだ」と。
  10. 多くのRails開発者は、異なるビューの間で共通に使用するパーシャルを保存するディレクトリとして、sharedディレクトリを使用します。著者は、複数のビューで共有するユーティリティパーシャルについてはsharedフォルダに保存し、文字どおり全ページ (サイトレイアウトの一部として) 共通のパーシャルについてはlayoutsディレクトリへ保存することを好んでいます (sharedディレクトリは第7章で作成します)。著者はこのように分割保存するのが論理的であると考えますが、sharedフォルダにすべて保存しても問題なく動作します。
  11. footerタグと.footerクラスを両方使用していることについて疑問に思う方がいるかもしれません。その理由は、footerタグとする方が読み手にとって意味が明確であるのと、.footerクラスはBootstrapで使用するためです。footerdivに置き換えても動作は変わりません。
  12. このチュートリアル構成は、Michael Erasmusによる素晴らしいブログ記事「5分でわかるRails 3のAsset Pipeline (英語)」をもとにしています。詳細についてはRailsガイドの「アセットパイプライン」の項を参照してください。
  13. Sassでもサポートされている古い.sassというフォーマットでは、冗長性の少ない (括弧の少ない) 新しい言語を定義しますが、既存のプロジェクトには若干不便であり、既にCSSに慣れ親しんだ人にとっては学習が面倒でもあります。
  14. 何人かの開発者は「1つのテストに複数のアサーションを入れるべきではない」と強く主張するでしょう。 この演習は不必要に複雑で、もし各テストの直前に共通のセットアップ用タスクがあれば、たしかに不要な負荷がかかることでしょう。しかし、よく書かれたテストは一貫したストーリーのようになり、人間にとって理解しやすいです。ストーリーを独立した場面ごとに分割されてしまうと、物語調ではなくなってしまいます。このことから、複数のアサーションを1つのテストにまとめるようにして、(minitestを通して) Rubyにどのセリフで間違ったのかを話させるようにしています。
Railsチュートリアルは,Ruby/Rails のアジャイル開発を得意とする YassLab によって運営・保守されております.
継続的に良いコンテンツを提供する為に,電子書籍スクリーンキャストのご購入を検討して頂けると幸いです m(_ _)m
スポンサーシップや商用利用などに関するご相談がありましたら,お問い合わせページよりお気軽にご連絡ください :)