Ruby on Rails
チュートリアル

実例を使ってRailsを学ぼう

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

第2版 目次

  1. 第1章 ゼロからデプロイまで
    1. 1.1はじめに
      1. 1.1.1読者の皆さまへ
      2. 1.1.2 Railsとスケールについて
      3. 1.1.3この本における取り決め
    2. 1.2 さっそく動作させる
      1. 1.2.1開発環境
        1. IDE
        2. テキストエディタとコマンドライン
        3. ブラウザ
        4. 使用するツールについて
      2. 1.2.2Ruby、RubyGems、Rails、Git
        1. Railsインストーラ (Windows)
        2. Gitのインストール
        3. Rubyのインストール
        4. RubyGemsのインストール
        5. Railsのインストール
      3. 1.2.3最初のアプリケーション
      4. 1.2.4 Bundler
      5. 1.2.5 rails server
      6. 1.2.6Model-view-controller (MVC)
    3. 1.3Gitによるバージョン管理
      1. 1.3.1インストールとセットアップ
        1. 初めてのシステムセットアップ
        2. 初めてのリポジトリセットアップ
      2. 1.3.2追加とコミット
      3. 1.3.3Gitのメリット
      4. 1.3.4 GitHub
      5. 1.3.5ブランチ (branch)、変更 (edit)、 コミット (commit)、マージ (merge)
        1. ブランチ (branch)
        2. 変更 (edit)
        3. コミット (commit)
        4. マージ (merge)
        5. プッシュ (push)
    4. 1.4デプロイする
      1. 1.4.1 Herokuのセットアップ
      2. 1.4.2 Herokuにデプロイする (1)
      3. 1.4.3 Herokuにデプロイする (2)
      4. 1.4.4 Heroku コマンド
    5. 1.5 最後に
  2. 第2章デモアプリケーション
    1. 2.1 アプリの計画
      1. 2.1.1ユーザーのモデル設計
      2. 2.1.2マイクロポストのモデル設計
    2. 2.2Users リソース
      1. 2.2.1ユーザーページを探検する
      2. 2.2.2 MVCの挙動
      3. 2.2.3Users リソースの欠点
    3. 2.3Microposts リソース
      1. 2.3.1マイクロポストのページを探検する
      2. 2.3.2マイクロポストをマイクロにする
      3. 2.3.3ユーザーとマイクロポストをhas_manyで関連づける
      4. 2.3.4継承の階層
      5. 2.3.5デモアプリケーションのデプロイ
    4. 2.4最後に
  3. 第3章ほぼ静的なページの作成
    1. 3.1静的ページ
      1. 3.1.1「本当に」静的なページ
      2. 3.1.2Railsによる静的なページ
    2. 3.2最初のテスト
      1. 3.2.1テスト駆動開発
      2. 3.2.2ページの追加
        1. 赤 (Red)
        2. 緑 (Green)
        3. リファクタリング
    3. 3.3少しだけ動的なページ
      1. 3.3.1タイトル変更をテストする
      2. 3.3.2タイトルのテストをパスさせる
      3. 3.3.3埋め込みRuby
      4. 3.3.4レイアウトを使って重複を解消する
    4. 3.4最後に
    5. 3.5演習
    6. 3.6高度なセットアップ
      1. 3.6.1bundle execを追放する
        1. RVM Bundler の統合
        2. binstubsオプション
      2. 3.6.2Guardによるテストの自動化
      3. 3.6.3Spork を使ったテストの高速化
        1. GuardにSporkを導入する
      4. 3.6.4Sublime Text上でテストする
  4. 第4章 Rails風味のRuby
    1. 4.1動機
    2. 4.2文字列(string)とメソッド
      1. 4.2.1コメント
      2. 4.2.2文字列
        1. 出力
        2. シングルクォート内の文字列
      3. 4.2.3オブジェクトとメッセージ受け渡し
      4. 4.2.4メソッドの定義
      5. 4.2.5 title ヘルパー、再び
    3. 4.3他のデータ構造
      1. 4.3.1配列と範囲演算子
      2. 4.3.2ブロック
      3. 4.3.3ハッシュとシンボル
      4. 4.3.4 CSS、再び
    4. 4.4 Ruby におけるクラス
      1. 4.4.1コンストラクタ
      2. 4.4.2クラス継承
      3. 4.4.3組込みクラスの変更
      4. 4.4.4コントローラクラス
      5. 4.4.5ユーザークラス
    5. 4.5最後に
    6. 4.6演習
  5. 第5章レイアウトを作成する
    1. 5.1構造を追加する
      1. 5.1.1ナビゲーション
      2. 5.1.2BootstrapとカスタムCSS
      3. 5.1.3パーシャル (partial)
    2. 5.2SassとAsset Pipeline
      1. 5.2.1Asset Pipeline
        1. アセットディレクトリ
        2. マニフェストファイル
        3. プリプロセッサエンジン
        4. 本番環境での効率性
      2. 5.2.2素晴らしい構文を備えたスタイルシート
        1. ネスト
        2. 変数
    3. 5.3レイアウトのリンク
      1. 5.3.1 ルートのテスト
      2. 5.3.2 Railsのルート
      3. 5.3.3名前付きルート
      4. 5.3.4RSpecを洗練させる
    4. 5.4ユーザー登録: 最初のステップ
      1. 5.4.1ユーザーコントローラ
      2. 5.4.2ユーザー登録URI
    5. 5.5最後に
    6. 5.6演習
  6. 第6章ユーザーのモデルを作成する
    1. 6.1 Userモデル
      1. 6.1.1データベースの移行
      2. 6.1.2modelファイル
        1. モデル注釈
        2. アクセス可能な属性
      3. 6.1.3ユーザーオブジェクトを作成する
      4. 6.1.4ユーザーオブジェクトを検索する
      5. 6.1.5ユーザーオブジェクトを更新する
    2. 6.2ユーザーを検証する
      1. 6.2.1最初のユーザーテスト
      2. 6.2.2プレゼンスを検証する
      3. 6.2.3長さを検証する
      4. 6.2.4フォーマットを検証する
      5. 6.2.5一意性を検証する
        1. 一意性の警告
    3. 6.3セキュアなパスワードを追加する
      1. 6.3.1暗号化されたパスワード
      2. 6.3.2パスワードと確認
      3. 6.3.3ユーザー認証
      4. 6.3.4ユーザーがセキュアなパスワードを持っている
      5. 6.3.5ユーザーを作成する
    4. 6.4最後に
    5. 6.5演習
  7. 第7章ユーザー登録
    1. 7.1ユーザーを表示する
      1. 7.1.1デバッグとRails環境
      2. 7.1.2ユーザーリソース
      3. 7.1.3ファクトリーを使用してユーザー表示ページをテストする
      4. 7.1.4gravatar画像とサイドバー
    2. 7.2ユーザー登録フォーム
      1. 7.2.1ユーザー登録のためのテスト
      2. 7.2.2form_forを使用する
      3. 7.2.3フォームHTML
    3. 7.3ユーザー登録失敗
      1. 7.3.1正しいフォーム
      2. 7.3.2ユーザー登録のエラーメッセージ
    4. 7.4ユーザー登録成功
      1. 7.4.1登録フォームの完成
      2. 7.4.2flash
      3. 7.4.3実際のユーザー登録
      4. 7.4.4 SSLを導入して本番環境をデプロイする
    5. 7.5最後に
    6. 7.6演習
  8. 第8章サインイン、サインアウト
    1. 8.1セッション、サインインの失敗
      1. 8.1.1Sessionコントローラ
      2. 8.1.2サインインをテストする
      3. 8.1.3サインインのフォーム
      4. 8.1.4確認フォームを送信する
      5. 8.1.5フラッシュメッセージを表示する
    2. 8.2、サインイン成功
      1. 8.2.1[このアカウント設定を保存する]
      2. 8.2.2正しいsign_inメソッド
      3. 8.2.3現在のユーザー
      4. 8.2.4レイアウトリンクを変更する
      5. 8.2.5ユーザー登録と同時にサインインする
      6. 8.2.6サインアウトする
    3. 8.3Cucumberの紹介 (オプション)
      1. 8.3.1インストールと設定
      2. 8.3.2フィーチャーとステップ
      3. 8.3.3対比: RSpecのカスタムマッチャー
    4. 8.4最後に
    5. 8.5演習
  9. 第9章 ユーザーの更新・表示・削除
    1. 9.1ユーザーを更新する
      1. 9.1.1編集フォーム
      2. 9.1.2編集の失敗
      3. 9.1.3編集の成功
    2. 9.2認可
      1. 9.2.1ユーザーのサインインを要求する
      2. 9.2.2正しいユーザーを要求する
      3. 9.2.3フレンドリーフォワーディング
    3. 9.3すべてのユーザーを表示する
      1. 9.3.1ユーザーインデックス
      2. 9.3.2サンプルのユーザー
      3. 9.3.3ページネーション
      4. 9.3.4パーシャルのリファクタリング
    4. 9.4ユーザーを削除する
      1. 9.4.1管理ユーザー
        1. attr_accessible属性再び
      2. 9.4.2 destroyアクション
    5. 9.5最後に
    6. 9.6演習
  10. 第10章ユーザーのマイクロポスト
    1. 10.1Micropostモデル
      1. 10.1.1基本的なモデル
      2. 10.1.2Accessible属性と最初の検証
      3. 10.1.3User/Micropostの関連付け
      4. 10.1.4マイクロポストを改良する
        1. デフォルトのスコープ
        2. Dependent: destroy
      5. 10.1.5コンテンツの検証
    2. 10.2マイクロポストを表示する
      1. 10.2.1ユーザー表示ページの拡張
      2. 10.2.2マイクロポストのサンプル
    3. 10.3マイクロポストを操作する
      1. 10.3.1アクセス制御
      2. 10.3.2マイクロポストを作成する
      3. 10.3.3フィードの原型
      4. 10.3.4マイクロポストを削除する
    4. 10.4最後に
    5. 10.5演習
  11. 第11章ユーザーをフォローする
    1. 11.1Relationshipモデル
      1. 11.1.1データモデルの問題 (および解決策)
      2. 11.1.2User/relationshipの関連付け
      3. 11.1.3検証
      4. 11.1.4フォローしているユーザー
      5. 11.1.5フォロワー
    2. 11.2フォローしているユーザー用のWebインターフェイス
      1. 11.2.1フォローしているユーザーのサンプルデータ
      2. 11.2.2統計とフォロー用フォーム
      3. 11.2.3「フォローしているユーザー」ページと「フォロワー」ページ
      4. 11.2.4[フォローする] ボタン (標準的な方法)
      5. 11.2.5[フォローする] ボタン (Ajax)
    3. 11.3ステータスフィード
      1. 11.3.1動機と計画
      2. 11.3.2フィードを初めて実装する
      3. 11.3.3サブセレクト
      4. 11.3.4新しいステータスフィード
    4. 11.4最後に
      1. 11.4.1サンプルアプリケーションの機能を拡張する
        1. 返信機能
        2. メッセージ機能
        3. フォロワーの通知
        4. パスワードリマインダー
        5. ユーザー登録の確認
        6. RSSフィード
        7. REST API
        8. 検索機能
      2. 11.4.2読み物ガイド
    5. 11.5演習
  12. 第12章Rails 4.0へのアップグレード
    1. 12.1Rails 3.2からRails 4.0へのアップグレード
      1. 12.1.1Rails 4.0のセットアップ
      2. 12.1.2テストをパスするようにする
      3. 12.1.3特定の問題
        1. モデル
        2. コントローラとビュー
      4. 12.1.4仕上げ
      5. 12.1.5追加機能
    2. 12.2Strong parameters
    3. 12.3セキュリティのアップデート
      1. 12.3.1秘密鍵
      2. 12.3.2記憶トークンを暗号化する

前書き

私が前にいた会社 (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日間かけて一気に読破しました。最初から最後まで、途中を飛ばさずに読んでください。それが、最も有益な本書の読み方です。

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

デレックシバーズ (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 Bates、 Geoffrey Grosenbach、 Peter Cooper、 Matt Aimonetti、 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 チュートリアル」という、Ruby on Rails を使って初めて Web アプリケーションを開発する際に、最もよく参考にされる本の著者です。以前は、(今ではすっかり古くなってしまいましたが)「RailsSpace」という本の執筆および開発に携わったり、また、 一時人気を博した Ruby on Rails ベースのソーシャルネットワーキングプラットフォーム「Insoshi」の開発にも携わっていました。なお、2011年には、Rails コミュニティへの高い貢献が認められて、Ruby Hero Award を受賞しました。ハーバード大学卒業後、カリフォルニア工科大学物理学博士号を取得し、起業プログラム Y Combinator の卒業生でもあります。

著作権とライセンス

Ruby on Rails チュートリアル: 実例を使って Rails を学ぼう. Copyright © 2010 by Michael Hartl.Ruby on Rails チュートリアル内の全てのソースコードは、MIT ライセンスおよび Beerware ライセンスの元で提供されています。

(The MIT License)

Copyright (c) 2012 Michael Hartl

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * Michael Hartl wrote this code.As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day,
 * and you think this stuff is worth it, you can buy me a beer in return.
 * ----------------------------------------------------------------------------
 */

第12章Rails 4.0へのアップグレード

本章は、Railsを最新バージョンであるRails 4.0にアップグレードするために追加された補足資料です。本書はRails入門を目的としたチュートリアルであるため、その意味では本書のRails 3.2対応版とRails 4.0対応版には大きな違いは生じません。実際、本章で補足すべきRail 4.0の重要な新機能は、Strong Parameterしかありません。Rail 4.0を使用した本格的なWeb開発を学びたいという要望に応えて、Rails 4.0対応版のRailsチュートリアルも公開いたしました。オンライン版は無料にて提供、電子書籍版 (PDF/EPUB) は http://tatsu-zine.com/books/railstutorial から購入することができます。なお、Rails 3.2対応版とRails 4.0対応版の主な違いについては、Rails 4.0向けチュートリアルのコラム1.1を参照してください。

本章の最初の目的は、Railsチュートリアルのサンプルアプリケーションを、Rails 3.2からRails 4.0にアップグレードすることです (12.1)。次に、主要な変更点である、attr_accessible (6.1.2.2) からStrong Parameter (12.2) への変更について説明します。最後に、2つの小さな機能をサンプルアプリケーションに追加します。この追加機能は、Rails 4.0とは本質的には関係ありませんが、セキュリティ上の理由から、この場を借りて12.3で解説します。

加えて、本章の内容を補うためのスクリーンキャストも制作しました。こちらもrailstutorial.jp/screencasts から購入することができます。本スクリーンキャストは、サンプルアプリケーションをRails 3.2からRails 4.0にアップグレードするところをライブデモする動画です。Strong Parametersやセキュリティ上の更新を実際にデモしながら解説しています。

12.1Rails 3.2からRails 4.0へのアップグレード

Railsとそれを取り囲むエコシステムは比較的成熟してきましたが、Railsは今でも急速に変化し続けています。今回のようなメジャーな更新が発生すると、多くの細かな機能が損なわれるのが普通です。実際、著者自身も既存のRailsプロジェクトをその場でアップグレードしようとした際、しばしば苦い経験をしてきました。そしてそのたびに、最後にはrails newを使ってアプリケーションを最初から作り直すはめになってしまいました。それというのも、rails newによって生成される大量の設定ファイルにはさまざまな数値やデフォルト値が設定されているのですが、これらの値はバージョンによって異なっているからです。そしてこれらの値を既存のプロジェクトに反映する作業は非常に困難です。そこで本節では、次のような方針でアップグレードの作業を進めることにします。最初に、空のRails 4.0のプロジェクトを作成し、プロジェクトをとにかく動く状態にします。その後、既存のプロジェクトから順次コードを移植していき、アプリケーションが正しく動作することを1つずつ確認しながら、作業を進めていきます。

Railsアプリケーションのアップグレードは難易度の高い作業です。したがって、本節の難易度も高くなっています。本節をお読みいただければわかるように、Railsのアプリケーションのアップグレードは、残念ながら「本に載っている手順に従うだけで完了するような作業」ではありません。実際、本節で行うのは演習の延長線上にある応用作業です。これまでの演習との違いは、多くの役に立つヒントとマニュアル (スクリーンキャスト) が用意されている点です。たとえば「アップグレードされたスクリーンキャスト」では、著者が悪戦苦闘の末にアップグレードを成功させる様子を見ることができます。なお、「Railsアプリケーションのアップグレードの途中で行き詰まってしまったけど、スクリーンキャストは購入したくない」という場合は、GitHub上のアップグレード済みサンプルアプリケーションを参考にしてください。

12.1.1Rails 4.0のセットアップ

Rails 4.0を使ってアプリケーションをセットアップする手順は、第1章から第3章までの手順と実質的には同じです。具体的には、1) RVMのgemsetの作成 (またはrbenvの環境構築)、2) Railsのインストール、3) Bundlerを使ったgemのインストール、4) RSpecの設定、という手順で進めます。

もしRVMまたはrbenvを既に使っているのであれば、Rails 4.0対応版チュートリアルの第1章に従って、システムを設定することできます。たとえばRVMを使っている場合は、Rails 4.0のサンプルアプリケーション用に新しくgemsetを作成することをお勧めします。その場合は次のコマンドを実行します。

$ rvm use 2.0.0@railstutorial_rails_4_0_upgrade --create

次に、Rails 4.0をインストールします。

$ gem install rails -v 4.0.0

次に、アプリケーションをアップグレードするための新規プロジェクトを作成します。

$ cd ~/rails_projects
$ rails new sample_app_4_0 --skip-test-unit
$ cd sample_app_4_0

この時点で、rails serverを実行してアプリケーションをローカルで走らせ、正常に動作していることを確認してください。

次に、アップグレードに必要な全てのgemをインストールします。具体的には、Gemfileをリスト12.1のように書き換えます。

リスト12.1 サンプルアプリケーションのアップグレードに必要なGemfile
source 'https://rubygems.org'
ruby '2.0.0'

gem 'rails', '4.0.0'
gem 'bootstrap-sass', '2.3.2.0'
gem 'bcrypt-ruby', '3.0.1'
gem 'faker', '1.1.2'
gem 'will_paginate', '3.0.4'
gem 'bootstrap-will_paginate', '0.0.9'

group :development, :test do
  gem 'sqlite3', '1.3.7'
  gem 'rspec-rails', '2.13.1'
  # The following optional lines are part of the advanced setup.
  # gem 'guard-rspec', '2.5.0'
  # gem 'spork-rails', github: 'sporkrb/spork-rails'
  # gem 'guard-spork', '1.5.0'
  # gem 'childprocess', '0.3.6'
end

group :test do
  gem 'selenium-webdriver', '2.0.0'
  gem 'capybara', '2.1.0'
  gem 'factory_girl_rails', '4.2.0'
  gem 'cucumber-rails', '1.3.0', :require => false
  gem 'database_cleaner', github: 'bmabey/database_cleaner'

  # Uncomment this line on OS X.
  # gem 'growl', '1.0.3'

  # Uncomment these lines on Linux.
  # gem 'libnotify', '0.8.0'

  # Uncomment these lines on Windows.
  # gem 'rb-notifu', '0.0.4'
  # gem 'win32console', '1.3.2'
end

gem 'sass-rails', '4.0.0'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.0'
gem 'jquery-rails', '2.2.1'
gem 'turbolinks', '1.1.1'
gem 'jbuilder', '1.0.2'

group :doc do
  gem 'sdoc', '0.3.20', require: false
end

group :production do
  gem 'pg', '0.15.1'
  gem 'rails_12factor', '0.0.2'
end

gem 'protected_attributes'

リスト12.1の最後の行に注目してください。このgem は、attr_accessible (6.1.2.2) をRails 4.0のアプリケーションでも使えるようにするために必要なgemです。

gem 'protected_attributes'

なお、attr_accessibleをStrong Parametersに変更し終わったらこのgemは必要なくなるので、このgemは12.2で削除する予定です。

いつもと同様に、bundle installを実行することでリスト12.1のgemをインストールできます。また、bundle updateも実行しておいてください (念のため、もう一度bundle installを実行しておくと安心です)。

$ bundle install --without production
$ bundle update
$ bundle install

gemをインストールする際に (rspec-railsと一緒に) RSpecもインストールされますが、generateコマンドを使ってRSpecを再度インストールする必要があります。

$ rails generate rspec:install

それではRails 3.2のアプリケーションの移植作業を始めましょう。最初に、生成されたREADMEファイルを削除して、Markdown 版の README (リスト3.2) に置き換えてください。

$ rm -f README.rdoc
$ cp ../sample_app_2nd_ed/README.md .
$ cp ../sample_app_2nd_ed/.rspec .

このとき、RSpec の設定ファイル (.rspec) も一緒にコピーしておいてください。

この時点で、サンプルアプリケーションをGit管理下に置くのが賢い方法です。Railsのアップグレードのような多くのエラーが発生する作業では、Gitは本当に役に立ちます。また、今のうちにRailsが自動生成した.gitignoreファイルをリスト12.2の内容に置き換えておくことをお勧めします。

リスト12.2 サンプルアプリケーションの .gitignore ファイル。
# Ignore bundler config.
/.bundle

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*.log
/tmp

# Ignore other unneeded files.
doc/
*.swp
*~
.project
.DS_Store
.idea
.secret

リスト12.2では、.secretファイルを無視する行が追加されていることに注目してください。このファイルは、セキュリティの向上のために生成されたファイルです。詳細については12.3.1で説明します。

最後に、Capybaraのドメイン固有言語 (DSL: domain-specific language) を明示的にインクルードする設定が必要です。これは、RSpecのrequest spec (統合テスト) 機能を使うために、デフォルトの文法を変更しておく必要があるからです。実際には、リスト12.3に示すように、spec_helper.rbに1行追加するだけで設定できます。

リスト12.3 Capybara DSLをRSpecに追加する。
spec/spec_helper.rb
.
.
.
RSpec.configure do |config|
  .
  .
  .
  config.include Capybara::DSL
end
バージョン管理にGitを使っているのであれば、この時点で最初のコミットを行うとよいでしょう。
$ git init
$ git add .
$ git commit -m "Initialize repository"

本書の内容を簡潔にするために、以後、Gitコミットの指示を省略しますが、折を見てGitコミットするように心掛けてください。

12.1.2テストをパスするようにする

アップグレードを完了するために、本チュートリアルで全面的に使用されているテストスイートをここでも活用することにします。このようなときには、既存アプリケーションのtestディレクトリまたはテストファイルを (一度にすべてではなく) 1つずつ新しいRailsプロジェクトにコピーし、そのたびにそれに対応するアプリケーションコードを順次コピーする、という手順をお勧めします。最初はテストを実行できる状態にするだけで試行錯誤が必要になることでしょう。それを終え、実際にテストを行うと、当初はほとんどの場合失敗する (赤色になる) はずです。その状態からファイルを変更して、このテストがパスする (緑色になる) ようになればよいわけです。ファイルを変更するとは、つまりそのテストに対応するコードを既存のアプリケーションからコピーしてくるということです。ただし、Rails 3.2とRails 4.0の違い、または関連するgem (特にRSpecとCapybara) の違いによってはこのシナリオ通りにならず、コードをコピーしてきてもテストが失敗することがあります。

著者の経験では、最初にコピーするのはモデルのspecと、それに対応するモデルのコードにしておくのがよいようです。モデルのテストは、コントローラやビューの結合テストと比べるとモデル内で完結している傾向が高いためです。そこで、モデルをテストできるようにするために最初にマイグレーションからコピーしましょう。

$ cp -r ../sample_app_2nd_ed/db/migrate db/
$ rake db:migrate
$ rake test:prepare

../sample_app_2nd_ed/db/migrateの末尾にスラッシュを追加しないよう注意してください。システムによっては、マイグレーションファイルがコピーされてもディレクトリがコピーされないことがあります。なお、Rails 4.0ではrake db:test:prepareコマンドを使用するのが一般的ですが、従来のrake db:test:prepareコマンドも問題なく動作します。

以後、このようにテストとアプリケーションを既存のアプリケーションから順次新しいアプリケーションにコピーすることを繰り返し、移行を完了させます。コピーに使用するツールは、コマンドラインでもGUIファイルブラウザでも好みのもので構いません。

$ cp -r ../sample_app_2nd_ed/spec/models spec/
$ cp -r ../sample_app_2nd_ed/app/models app/

ファイルのコピー時にはエラーが発生することも多く、システム環境に依存するコピー項目もあるので、本書ではコピーするファイルをすべての場合について列挙することはしません。ファイルをどのような順序でコピーするかについては、各自にお任せすることにします。

特に注意して頂きたいのが、generateで生成されたファイル (アプリケーションレイアウトapplication.html.erbなど) には重要なコードが含まれていることがあり、単純な上書きコピーを行えない場合があるということです。このような場合には、ご面倒でもコピー元とコピー先のファイルを開き、内容を確認しながら必要なコードだけを手動でコピーしてください (スクリーンキャストはこういう作業の説明が楽ですね)。

12.1.3特定の問題

アップグレードにともなって発生する多数の問題を事前にすべて予測することは、一般的には極めて困難です。本章では基本的に、一般的な戦略を述べるだけにしておきます。著者が遭遇した特定の問題についてはある程度記載いたしましたが、すべてのトラブルを網羅することは事実上不可能ですので、どうかご容赦願います。アップグレード作業にはどうしても相当なフラストレーションがつきまといます。この困難を突破するには、とにかく忍耐、とにかくネット検索、それしかありません (ご心配なく、ちゃんとカンニングペーパーも用意してあります)。

モデル

protected_attributes gem (リスト12.1) の動作がRails 3.2の「アクセス可能な属性」と異なっているため、マスアサインメントのセキュリティエラーをテストするコードは4.0では動作しなくなりました。このテストコードは削除する必要があります。たとえば、以下のコードはUserモデルのspec (spec/models/user_spec.rb)ですが、これは削除が必要です。

describe "accessible attributes" do
  it "should not allow access to admin" do
    expect do
      User.new(admin: true)
    end.to raise_error(ActiveModel::MassAssignmentSecurity::Error)
  end
end

これに対応するテストがMicropostモデルとRelationshipモデルにもあるので、それらも削除してください。

モデルでは他にも、デフォルトのスコープ (10.1.4.1) に関して以下の非推奨警告が表示されます。

DEPRECATION WARNING: Calling #scope or #default_scope
with a hash is deprecated.

この問題は、次のように修正できます。

default_scope order: 'microposts.created_at DESC'

上のコードを以下に置き換えます。

default_scope -> { order('created_at DESC') }

置き換え対象のコードはapp/models/micropost.rbにあります。Rails 4.0のdefault_scopeは、従来のハッシュに代えて、Ruby 1.9で導入されたlambdaを引数に取るように変更されました。->は、Ruby 1.9で導入されたlambdaの略記法です。詳細については4.0チュートリアルの第10章を参照してください。

Micropost spec (spec/models/micropost_spec.rb) もわずかに変更が必要です。dupメソッドを使用して@user.micropostsを複製していますが、これをto_aメソッド (配列への変換) に置き換えます。以下はdupを使用した既存のコードです。

it "should destroy associated microposts" do
  microposts = @user.microposts.dup
  @user.destroy
  microposts.should_not be_empty
  microposts.each do |micropost|
    Micropost.find_by_id(micropost.id).should be_nil
  end
end

理由は不明ですが、dup呼び出しは Rails 4.0では動作しなくなりました。to_aに置き換えることで正常に動作します。

it "should destroy associated microposts" do
  microposts = @user.microposts.to_a
  @user.destroy
  expect(microposts).not_to be_empty
  microposts.each do |micropost|
    expect(Micropost.where(id: micropost.id)).to be_empty
  end
end

コントローラとビュー

Relationshipsはテストの量がかなり少ないので、次はRelationshipsのテストを行うことをお勧めします。テストを行うと、ルーティングが失敗します。これは、Rails 4.0ではconfig/routes.rbmatchでHTTPメソッドをviaで明示的に指定することが要求されるようになったためです。

  resources :users do
    member do
      get :following, :followers
    end
  end
  resources :sessions,      only: [:new, :create, :destroy]
  resources :microposts,    only: [:create, :destroy]
  resources :relationships, only: [:create, :destroy]
  root to: 'static_pages#home'
  match '/signup',  to: 'users#new',            via: 'get'
  match '/signin',  to: 'sessions#new',         via: 'get'
  match '/signout', to: 'sessions#destroy',     via: 'delete'
  match '/help',    to: 'static_pages#help',    via: 'get'
  match '/about',   to: 'static_pages#about',   via: 'get'
  match '/contact', to: 'static_pages#contact', via: 'get'

次はrequest specです。

it { should have_selector('title', text: 'Sign up') }

上のようなコードは、Capybaraの変更が原因で失敗します。Capybaraのhave_selectorは画面に実際に表示される要素にしか適用できなくなりました (ページタイトルは一部のブラウザではトップバーに表示されますが、「実際に表示される要素」としては扱われません)。これを解決するには、新しいhave_titleメソッドを使用します。

it { should have_title(text: 'Sign up') }

正規表現による置き換えをサポートするエディタ (VimやSublime Textなど) を使用できる場合は、以下の正規表現を使用して一括置き換えを行えます。

have_selector\('title', text: (.*?)\)

置き換える文字列は以下を使用します。

have_title($1)

ただし、静的なページ用のspec (spec/requests/static_pages_spec.rb) では括弧を使用していないので、以下の正規表現も使用する必要があります。

have_selector 'title', text: (.*?)

置き換える文字列は以下を使用します。

have_title $1

(テキストエディタを使用して置き換えを行うという部分の意味がよくわからない場合は、スクリーンキャストを購入いただければその中で実際の操作をお見せいたします)

Capybaraの変更によって動かなくなった部分は他にもあります。inputフィールドのtitleタグは画面に表示されないので、have_selectorが効かなくなりました。これを解決するには、強力なXPathメソッドを使用します。このメソッドはHTML5を含むXMLドキュメントの要素を自在にナビゲートできます。変更は以下のとおりです。

describe "toggling the button" do
  before { click_button "Follow" }
  it { should have_selector('input', value: 'Unfollow') }
end
.
.
.
describe "toggling the button" do
  before { click_button "Unfollow" }
  it { should have_selector('input', value: 'Follow') }
end

上を以下のように置き換えます。

describe "toggling the button" do
  before { click_button "Follow" }
  it { should have_xpath("//input[@value='Unfollow']") }
  end
.
.
.
describe "toggling the button" do
  before { click_button "Unfollow" }
  it { should have_xpath("//input[@value='Follow']") }
end

置き換えの対象はspec/requests/user_pages_spec.rbにあります。

著者が遭遇した最後のエラーは、以下のコードのあいまいな箇所についてCapybaraが警告してきたことです。

it "should be able to delete another user" do
  expect { click_link('delete') }.to change(User, :count).by(-1)
end

上のコードはspecs/requests/user_pages_spec.rbにあります。以前のCapybaraは、古いdeleteリンクを問題なくクリックすることができましたが、新しいバージョンでは動作が厳密になり、リンクをCSS idなどで正確に指定することが要求されるようになりました。これはもちろん歓迎すべき変更です。このおかげで、テスト中に誤ったリンクがクリックされずに済むからです。しかしこのチュートリアルのサンプルでは、どのリンクがクリックされるかは重要ではありません。これを解決するには、match: :firstオプションハッシュを渡して、最初に見つけたdeleteリンクをクリックするようCapybaraに指示します。

it "should be able to delete another user" do
  expect do
    click_link('delete', match: :first)
  end.to change(User, :count).by(-1)
end

これでテストスイートはパスするはずです。

12.1.4仕上げ

残る作業は、スタイルシートのコピーと、Bootstrap JavaScriptをapplication.jsに追加することです。

$ cp -r ../sample_app_2nd_ed/app/assets/* app/assets/

上のコピー中にapplication.jsを上書きしないように注意してください (上書きの警告が表示されたら [いいえ] をクリックします)。次に、application.jsの内容を12.4のとおりに更新し、Bootstrap Javascriptを追加します。

リスト12.4 Bootstrap JavaScriptを追加する。
app/assets/javascripts/application.js
.
.
.
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap
//= require_tree .

ここまで問題なく進めることができれば、アプリケーションは4.0で動作するようになるはずです。以下のようにデータベースにサンプルデータを導入してローカルサーバーで実行することで、実際の動作を確認できます。

$ cp ../sample_app_2nd_ed/lib/tasks/* lib/tasks
$ rake db:populate
$ rails server

(上の手順ではスタイルシートがコピーされないことに気付いた方がいるかもしれません。著者もスクリーンキャストを制作中に気付きました。でもこのぐらいは簡単に修正できるはずです)

12.1.5追加機能

Rails 4.0には、本章の範疇を超える追加機能がいくつかあります。中でも代表的なのはTurbolinksでしょう。これはJavaScriptを使用してアプリケーションのユーザーインターフェイスを高速化する技法です。他にRussian doll caching (一度描画したHTMLをインテリジェントに保存して不要な再描画を抑制する新機能) もあります。このようなやや高度なトピックを理解するには、RailsCastsが便利です。

12.2Strong parameters

いよいよ、(Railsチュートリアルにとっては) Rails 3.2とRails 4.0の最大の違いであるStrong Parametersについて説明します。これはattr_accessibleを置き換えるものであり、マスアサインメントの脆弱性 (9.4.1.1) を防止するためのものです。attr_accessibleはモデルに対して適用しますが、Strong Parametersはコントローラ層に対して適用するという点が大きく異なります。認証や認可はコントローラで行われますが、それと同じ場所に適用するという点で、Strong Parametersは従来よりも適切な手法です。

以下の作業は、12.1でアップグレード完了したアプリケーションに対して行うことをお勧めしますが、GitHub上の完成品を使用してもかまいません。後者の場合は、ここより先の変更を適用していないブランチがありますので、それをチェックアウトすることをお勧めします。

$ git clone https://github.com/mhartl/sample_app_4_0_upgrade
$ cd sample_app_4_0_upgrade/
$ git checkout -t origin/only-upgraded

Strong Parametersを実装するために、最初にprotected_attributes gemをGemfileから削除してください (リスト12.1)。次に、UserモデルとMicropostモデルからattr_accessibleを削除します。

Strong parametersを使用して、どのパラメータを必須とし、どのパラメータを許可するかを指定できます。さらに、paramsハッシュをまるごと渡すとエラーが発生するようになっているので、Railsはデフォルトでマスアサインメントの脆弱性から保護されるようになりました。この変更により、テストは失敗するようになったはずです。

この場合、paramsハッシュでは:user属性を必須とし、名前、メールアドレス、パスワード、パスワードの確認の属性をそれぞれ許可し、それ以外を許可しないようにしたいと考えています。これは、以下のように記述することで行うことができます。

params.require(:user).permit(:name, :email, :password, :password_confirmation)

このコードの戻り値は、paramsハッシュのバージョンと、許可された属性です (:user属性がない場合はエラーになります)。

これらのパラメータを使いやすくするために、user_paramsという外部メソッドを使用するのが慣習になっています。このメソッドは適切な初期化ハッシュを返します。変更の結果をリスト12.5に示します。

リスト12.5 createアクションでStrong Parametersを使用する。
app/controller/users_controller.rb
class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(user_params)
    if @user.save
      sign_in @user
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user
    else
      render 'new'
    end
    end

  def edit
  end

  def update
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      sign_in @user
      redirect_to @user
    else
      render 'edit'
    end
  end
  .
  .
  .
  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end

同じようなコードを使用して、マイクロポストも同様に保護します (リスト12.6)。

リスト12.6 Micropostsコントローラのcreateアクション。
app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController
  .
  .
  .
  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to root_url
    else
      render 'static_pages/home'
    end
  end
  .
  .
  .
  private

    def micropost_params
      params.require(:micropost).permit(:content)
    end
end

以上で完了です。ついにサンプルアプリケーションはマスアサインメントの脆弱性に対する免疫を獲得しました。必要な更新も問題なく行えています。テストスイートを実行することでこのことを確認できます。

12.3セキュリティのアップデート

本章の最後に、小規模なセキュリティアップデートを2つ紹介します。通常、マイナーな変更の紹介は次の版に回すのですが、本章の冒頭に記したとおり、セキュリティ問題は常に最優先課題であるため、ここに記載いたします。

12.3.1秘密鍵

1番目のセキュリティ変更は、secret_token.rbを更新して秘密鍵を動的に生成するようにします。この秘密鍵は、セッション変数を暗号化するためにRailsで使用されます。この秘密鍵は、デフォルトではリスト12.7に示したようにランダムな文字列がハードコードされます。ソースコードが非公開のWebアプリケーションであればこれでもよいのですが、Githubなどでソースを公開する場合にはこのままでは危険です。このトークンを一般にさらしてしまうと、悪意のある攻撃者がセッションcookiesを改ざんする可能性が生じます。

リスト12.7 デフォルトの秘密トークンファイル。
config/initializers/secret_token.rb
# Be sure to restart your server when you modify this file.

# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
SampleApp::Application.config.secret_key_base = 'ced345e01611593
c1b783bae98e4e56dbaee787747e92a141565f7c61d0ab2c6f98f7396fb4b178
258301e2713816e158461af58c14b695901692f91e72b6200'

これを解決する方法は、秘密鍵をローカルで動的に生成してファイルに保存することです。実はこの問題はPhenoelit作 “Rails脆弱性自動レポート用ボット” が著者に親切にも警告してくれたおかげで気付いたもので、同ページに解決法も示されています。リスト12.8に示したように、この秘密鍵は必要に応じて読み出して利用されます。ここで特に注意して頂きたいのは、リスト12.2にも示したように、.secretファイルを.gitignoreに追記し、このファイルが間違っても一般からアクセス可能なリポジトリに置かれることのないようにする必要があるという点です。

リスト12.8 動的に秘密鍵を生成する秘密トークンファイル。
config/initializers/secret_token.rb
# Be sure to restart your server when you modify this file.

# Make sure your secret_key_base is kept private
# if you're sharing your code publicly, such as by adding
# .secret to your .gitignore file.

require 'securerandom'

def secure_token
  token_file = Rails.root.join('.secret')
  if File.exist?(token_file)
    # Use the existing token.
    File.read(token_file).chomp
  else
    # Generate a new token and store it in token_file.
    token = SecureRandom.hex(64)
    File.write(token_file, token)
    token
  end
end

SampleApp40::Application.config.secret_key_base = secure_token

12.3.2記憶トークンを暗号化する

最後のセキュリティアップデートは、記憶トークン (8.2.1) を暗号化することです。この暗号化のタイミングは、記憶トークンをユーザーのブラウザに保存した、かつ記憶トークンをデータベースに保存するでなくてはなりません。こうすることにより、万一データベースに対して不正アクセスが行われても、攻撃者は記憶トークンを使用して特定のユーザーとして不正にサインインすることはできなくなります。本章では必要なコードを示すだけにとどめます。詳細については、Rails 4.0用のチュートリアルの [このアカウント設定を保存する] を参照してください。

最初に、新しいメソッドを2つ追加します (Userインスタンスは不要なのでUserクラスに追加します)。これにより、新しいユーザートークンを生成してSHA1暗号化アルゴリズムで暗号化します (リスト12.9)。

リスト12.9 before_createコールバックを使用してremember_token属性を作成する。
app/models/user.rb
class User < ActiveRecord::Base
  before_save { self.email = email.downcase }
  before_create :create_remember_token
  .
  .
  .
  def User.new_remember_token
    SecureRandom.urlsafe_base64
  end

  def User.encrypt(token)
    Digest::SHA1.hexdigest(token.to_s)
  end
  .
  .
  .
  private

    def create_remember_token
      self.remember_token = User.encrypt(User.new_remember_token)
    end
end

次に、sign_inメソッドとcurrent_userメソッドを更新して、cookies内の新しいトークンを使用するようにし、続いてトークンを暗号化してデータベースに保存します (リスト12.10)。(追記: ソルト (暗号を強化するために元の平文に追加する短い文字列のこと) を追加していないSHA1ハッシュは一般にはセキュアではないと言われることがありますが、これは元の平文がパスワードのような短くかつランダムではない文字列の場合です。ここで暗号化する平文は十分長くかつランダムなので、生成されたハッシュは本質的にクラック不可能です。)

リスト12.10 セッションヘルパーを更新して記憶トークンを暗号化するようにする。
app/helpers/sessions_helper.rb
module SessionsHelper

  def sign_in(user)
    remember_token = User.new_remember_token
    cookies.permanent[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.encrypt(remember_token))
    self.current_user = user
  end
  .
  .
  .
  def current_user
    remember_token = User.encrypt(cookies[:remember_token])
    @current_user ||= User.find_by(remember_token: remember_token)
  end
  .
  .
  .
end

少々残念なことに、記憶トークンをセキュアにするための変更を行ったことにより、従来のテストで使用していたサインインの取り扱い方法が使えなくなってしまいました。これを解決するには、テストユーティリティのsign_inヘルパーを変更し、Capybaraを使用せずにオプションを渡すようにします (リスト12.11)。詳細については4.0用チュートリアルの [このアカウント設定を保存する] を参照してください。

リスト12.11 暗号化されたトークンを扱えるように更新されたsign_inヘルパー。
spec/support/utilities.rb
.
.
.
def sign_in(user, options={})
  if options[:no_capybara]
    # Capybaraを使用していない場合にもサインインする。
    remember_token = User.new_remember_token
    cookies[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.encrypt(remember_token))
  else
    visit signin_path
    fill_in "Email",    with: user.email
    fill_in "Password", with: user.password
    click_button "Sign in"
  end
end

no_capybaraオプションが必要な部分は3箇所のみです (リスト12.12の1箇所とリスト12.13の2箇所)。ここで、リスト12.13ではpatchメソッドが導入されたことに注目してください。これはHTTPのPATCH動詞に対応します。現時点ではPUTからPATCHへの変更は必須ではありませんが、Rails 4.0ではモデルオブジェクトの更新にはPATCHを使用することが推奨されており、将来のバージョンでは必須になる予定です。詳細については、4.0用のチュートリアル、特に「コラム 3.3 GETやその他のHTTPメソッドについて」を参照してください。

リスト12.12 Relationshipコントローラspecにno_capybaraオプションを追加する。
spec/controllers/relationships_controller_spec.rb
require 'spec_helper'

describe RelationshipsController do

  let(:user) { FactoryGirl.create(:user) }
  let(:other_user) { FactoryGirl.create(:user) }

  before { sign_in user, no_capybara: true }

  .
  .
  .
end
リスト12.13 認証ページspecにno_capybaraを追加する
spec/requests/authentication_pages_spec.rb
require 'spec_helper'

describe "Authentication" do
  .
  .
  .
  describe "authorization" do
    .
    .
    .
    describe "as wrong user" do
      let(:user) { FactoryGirl.create(:user) }
      let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
      before { sign_in user, no_capybara: true }

      describe "visiting Users#edit page" do
        before { visit edit_user_path(wrong_user) }
        it { should have_title(full_title('')) }
      end

      describe "submitting a PATCH request to the Users#update action" do
        before { patch user_path(wrong_user) }
        specify { response.should redirect_to(root_url) }
      end
    end

    describe "as non-admin user" do
      let(:user) { FactoryGirl.create(:user) }
      let(:non_admin) { FactoryGirl.create(:user) }

      before { sign_in non_admin, no_capybara: true }

      describe "submitting a DELETE request to the Users#destroy action" do
        before { delete user_path(user) }
        specify { response.should redirect_to(root_url) }
      end
    end
  end
end

以上で、必要な変更は完了です。テストスイートは緑色 (成功) になるはずです。3.2から4.0へのアップグレードについては、追加のスクリーンキャストもご覧ください。Strong Parametersやセキュリティアップデートの実装を手順を追って動画で解説しています。アップグレード中に行き詰まってしまった場合にもお勧めです。

アプリケーションのアップグレードとセキュリティアップデートの適用が完了したら、次はRails 4.0用Railsチュートリアルに進むことになるでしょう (そうするかどうかはもちろん皆様の自由です)。3.2用チュートリアルを完了させた今なら、4.0用チュートリアルは短時間で完了させることができるでしょう。4.0用チュートリアルもやっておけば、新機能について学ぶことができ、3.2用チュートリアルから十分に見直された記述に触れることもできます。4.0のすべては無理としても、3.2から4.0の変更点について言及しているコラム1.1は読んでおくことをお勧めします。