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静的ページ
    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.1Usersコントローラ
      2. 5.4.2 ユーザー登録用URL
    5. 5.5最後に
    6. 5.6演習
  6. 第6章ユーザーのモデルを作成する
    1. 6.1 Userモデル
      1. 6.1.1データベースの移行
      2. 6.1.2modelファイル
      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 Strong Parameters
      3. 7.3.3ユーザー登録のエラーメッセージ
    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. Strong Parameters、再び
      2. 9.4.2 destroyアクション
    5. 9.5最後に
    6. 9.6演習
  10. 第10章ユーザーのマイクロポスト
    1. 10.1Micropostモデル
      1. 10.1.1基本的なモデル
      2. 10.1.2最初の検証
      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演習

前書き

私が前にいた会社 (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 創始者

  1. 3日間で読破するのは異常です! 実際には3日以上かけて読むのが一般的です。

謝辞

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 © 2013 by Michael Hartl.

Ruby on Rails チュートリアル内の全てのソースコードは、MIT ライセンスおよび Beerware ライセンスの元で提供されています。(原文: All source code in the Ruby on Rails Tutorial is available jointly under the MIT License and the Beerware License.)

(訳注: "All source code" とはRailsチュートリアルの題材であるSNSのソースコードを指します。Railsチュートリアルという教材は上記ライセンスの元で提供されていないのでご注意ください)

(The MIT License)

Copyright (c) 2013 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.
 * ----------------------------------------------------------------------------
 */

第2章デモアプリケーション

この章では、Railsの強力な機能をいくつか紹介するためのデモアプリケーションを作成します。scaffoldジェネレータというスクリプトを使ってアプリケーションをすばやく生成する事により、高度なRailsプログラミングとWebプログラミングの概要を学びます。コラム1.1で述べたように、本書の以後の章では基本的にこの逆のアプローチを取り、少しずつアプリケーションを作りながら各段階と概念を説明する予定ですが、scaffoldはRailsアプリケーションの概要を素早くつかむには最適なので、この章でのみあえて使用することにします。生成されたRailsアプリケーションはブラウザのアドレスバーにURLを入力すれば動かすことができるので、これによりRailsアプリの構造、そしてRailsで推奨されているRESTアーキテクチャに関する洞察を得ることにします。

デモアプリケーションは、後に作成するサンプルアプリケーションと同様、ユーザーと、それに関連しているマイクロポストから成り立っています。このデモアプリケーションはもちろん動きますが完成品ではなく、しかも多くの手順が「魔法」のように思えるかもしれません。第3章以降で作成するサンプルアプリケーションでは同等の機能を1つ1つ手動で作成しますので、ご安心ください。その分時間がかかることになりますが、どうか最後まで本書にお付き合いいただければと思います。本書の目的は、scaffoldを使用した即席のアプローチによる表面的な理解ではなく、そこを突破してRailsを深いレベルまで理解することにあります。

2.1 アプリの計画

はじめに、デモアプリケーションをどのようなものにするのか、計画を立てましょう。1.2.3と同じく、railsコマンドでアプリケーションの骨格 (フォルダ構造、デフォルトで作成されるファイル類) を生成します。

$ cd rails_projects
$ rails new demo_app
$ cd demo_app

次に、Bundlerで使用するGemfile をテキストエディタで編集します。リスト2.1の内容に書き換えてください。

リスト2.1 デモアプリケーション用のGemfile
source 'https://rubygems.org'
ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0

gem 'rails', '4.0.5'

group :development do
  gem 'sqlite3', '1.3.8'
end

gem 'sass-rails', '4.0.5'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.1'
gem 'jquery-rails', '3.0.4'
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

リスト2.1の内容はリスト1.9と同じです。

1.4.1でも説明したとおり、--without productionオプションを追加することで、本番用のgemを除いたローカルgemをインストールします。

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

(第1章でも書きましたが、Bundlerでreadlineエラーが発生した場合は、Gemfilegem ’rb-readline’を追加してください)。

最後に、このデモアプリケーションをバージョン管理下に置きます。既に説明したとおり、railsコマンドを実行するとデフォルトの.gitignoreファイルが生成されます。システム環境によっては、このファイルをリスト1.7のように変更しておくと便利なことがあります。Gitリポジトリを初期化して最初のコミットを実行しておきます。

$ git init
$ git add .
$ git commit -m "Initial commit"
create_demo_repo_4_0
図2.1GitHubでデモアプリ用リポジトリを作成する。(拡大)

必須ではありませんが、リポジトリを新規作成して (図2.1) GitHubにプッシュすることもできます。

$ git remote add origin https://github.com/<username>/demo_app.git
$ git push -u origin master

(最初のアプリケーションのときと同様、GitHubリポジトリを初期化するときにREADMEを使用しないように注意してください。)

これで、アプリ自体を作成するための下準備が整いました。Webアプリケーションを作る際、アプリケーションで使用される構造を表すためのデータモデルを最初に作成しておくのが普通です。今回のデモアプリケーションでは、ユーザーと短いマイクロポストのみをサポートするマイクロブログを作成します。そこで、まずアプリケーションのユーザーで使用するモデルを作成 (2.1.1) し、次にマイクロポストで使用するモデルを作成します (2.1.2)。

2.1.1ユーザーのモデル設計

Webでのユーザー登録の方法が多岐にわたることからもわかるように、ユーザーという概念をデータモデルで表す方法はたくさんありますが、ここではあえて最小限の構造に抑えておきます。各ユーザーには、重複のない一意のキーとなるinteger型のID番号 (idと呼びます) を割り当て、このIDに加えて一般公開されるstring型の名前 (name)、そして同じくstring型のメールアドレス (email) を持たせます。メールアドレスはユーザー名としても使われます。ユーザーのデータモデルの概要を図2.2に示します。

demo_user_model
図2.2: ユーザー用のデータモデル

詳しくは6.1.1から解説しますが、図2.2のユーザー (users) はデータベースのテーブル (table) に相当します。また、idnameemailの属性はそれぞれテーブルのカラム (column: 列) に相当します。

2.1.2マイクロポストのモデル設計

マイクロポストのデータモデルはユーザー用のデータモデルよりもさらにシンプルです。idと、マイクロポストのテキスト内容を格納するstring型のcontentだけで構成されています1。しかし実際には、マイクロポストをユーザーと関連付ける (associate) 必要があるため、ポストのオーナーを記録するためのuser_idも追加します。これにより、データモデルは図2.3のようになります。

demo_micropost_model
図2.3 マイクロポストのデータモデル

2.3.3では、user_idという属性を使用して、1人のユーザーに複数のマイクロポストが関連付けられるという構造を簡潔に説明します。詳細は第10章で完全に説明します。

2.2Users リソース

ここでは、2.1.1で説明したユーザー用のデータモデルを、そのモデルを表示するためのWebインターフェイスに従って実装します。 このデータモデルとWebインターフェイスは、組み合わさってUsersリソースとなり、ユーザーというものを、HTTPプロトコル経由で自由に作成/読み出し/更新/削除できるオブジェクトとみなすことができるようになります。「はじめに」で約束したとおり、このUsersリソースはすべてのRailsプロジェクトに標準装備されているscaffoldジェネレータで生成します。scaffoldで生成された膨大なコードを今詳細に読む必要はありません。今の段階ではおそらく混乱するだけでしょう。

Railsのscaffoldは、rails generateスクリプトにscaffoldコマンドを渡すことで生成されます。scaffoldコマンドの引数には、リソース名を単数形にしたもの (この場合はUser) を使用し、必要に応じてデータモデルの属性をオプションとしてパラメータに追加します2

$ rails generate scaffold User name:string email:string
      invoke  active_record
      create    db/migrate/20130305221714_create_users.rb
      create    app/models/user.rb
      invoke      test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      invoke  resource_route
       route  resources :users
      invoke  jbuilder_scaffold_controller
      create  app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/show.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.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    jbuilder
       exist      app/views/users
      create      app/views/users/index.json.jbuilder
      create      app/views/users/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/users.js.coffee
      invoke    scss
      create      app/assets/stylesheets/users.css.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.css.scss

name:stringemail:stringオプションを追加することで、Userモデルの内容が図2.2の表のとおりになるようにします (なお、idパラメータはRailsによって自動的に主キーとしてデータベースに追加されるため、追加不要です)。

続いてデモアプリケーションの開発を進めるには、以下のようにRakeを使用してデータベースをマイグレート (migrate) する必要があります (コラム2.1)。

$ bundle exec rake db:migrate
==  CreateUsers: migrating =================================
-- create_table(:users)
   -> 0.0017s
==  CreateUsers: migrated (0.0018s) ========================

このコマンドは、単にデータベースを更新し、usersデータモデルを作成するためのものです (データベースのマイグレーションの詳細については 6.1.1以降で説明します)。なお、現在のGemfileに対応するバージョンのRakeが確実に実行されるようにするために、bundle execを使用してrakeを実行します (1.2.2.3で勧めたとおりにRVMを使用している場合は、bundle execは省略することもできます。本書では、基本的に省略せずに書くことにします。bundle execを実行しなくて良いようにする他の方法については、3.6.1を参照してください)。

ここまで実行すれば、以下のようにrails sコマンド (rails serverコマンドの短縮版) を実行してローカルWebサーバーを起動できるようになります。

$ rails s

これでhttp://localhost:3000/でデモアプリケーションをブラウザ表示できるようになっているはずです。

2.2.1ユーザーページを表示する

http://localhost:3000/をブラウザで表示すると、デフォルトのRailsページが表示されます (図1.3)。実は、Usersリソースを作成した時に、これ以外のさまざまな「ユーザーを扱うためのページ」が既に作成されています。たとえば、/usersを表示すればすべてのユーザーの一覧が表示されますし、/users/newを表示すれば新規ユーザー作成ページが表示されます。この節では以後、ユーザーに関連するページについて手短に説明します。その際、表2.1に記載されている、ページとURLの関係を参照するとわかりやすいと思います。

URLアクション用途
/usersindexすべてのユーザーを一覧するページ
/users/1showid=1のユーザーを表示するページ
/users/newnew新規ユーザーを作成するページ
/users/1/editeditid=1のユーザーを編集するページ
表2.1Usersリソースにおける、ページとURLの関係

まずはユーザーの一覧を表示するindexページから見てみましょう。もちろん、この時点ではまだユーザーは登録されていません (図2.4)。

demo_blank_user_index_rails_3
図2.4Usersリソース (/users) ページの最初の状態。(拡大)

ユーザーを新規作成するには、図2.5newページを表示します (注: ローカルのコンピュータで開発を行なっている場合は、URLのうちhttp://localhost:3000の部分は常に同じであるため、以後この部分は省略します)。 第7章では、このページをユーザー登録ページに転用します。

demo_new_user_rails_3
図2.5新規ユーザー作成ページ (/users/new)。(拡大)

テキストフィールドに名前とメールアドレスを入力して [Create User] ボタンを押してください。ユーザーが作成され、図2.6のようにshowページが表示されます (緑色のウェルカムメッセージは、 7.4.2で解説するflashという機能を使用して表示しています)。ここで、URLが/users/1と表示されていることに注目してください。ご想像のとおり、この数字1図2.2id属性そのものです。7.1では、このページをユーザーのプロファイルに作り変える予定です。

demo_show_user_rails_3
図2.6ユーザー表示用のページ (/users/1)。(拡大)

今度は、ユーザー情報を変更するためにeditページを表示してみましょう (図2.7)。この編集ページ上でユーザーに関する情報を変更し、[Update User] ボタンを押せば、デモアプリケーション内のユーザー情報が変更されます (図2.8)。(詳細は第6章で説明しますが、このユーザー情報は、Webアプリケーションの背後にあるデータベースに保存されています。) このサンプルアプリケーションでも、ユーザーを編集または更新する機能を9.1で実装します。

demo_edit_user_rails_3
図2.7ユーザー編集用のページ (/users/1/edit)。(拡大)
demo_update_user_rails_3
図2.8情報が更新されたユーザー。(拡大)

ここでnewページに戻り、ユーザーをもう1人作成してみましょう。indexページを表示してみると、図2.9のようにユーザーが追加されています。7.1ではもっと本格的なユーザー一覧ページを作成する予定です。

demo_user_index_two_rails_3
図2.92人目のユーザーが追加された一覧ページ (/users)。(拡大)

ユーザーの作成、表示、編集方法について説明しましたので、今度はユーザーを削除してみましょう (図2.10)。 図2.10の [Destroy] リンクをクリックするとユーザーが削除され、indexページのユーザーは1人だけになります (もしこのとおりにならない場合は、ブラウザのJavaScriptが有効になっているかどうかを確認してください。Railsでは、ユーザーを削除するリクエストを発行するときにJavaScriptを使用しています)。なお、9.4ではサンプルアプリケーションにユーザーを削除する機能を実装し、管理権限 (admin) を持つユーザー以外は削除を実行できないように制限をかけます。

demo_destroy_user_rails_3
図2.10ユーザーを削除する。(拡大)

2.2.2 MVCの挙動

これでUsersリソースの概略についての説明が終わりましたが、ここで1.2.6で紹介した MVC (Model-View-Controller = モデル-ビュー-コントローラ) パターンの観点からこのリソースを考察してみましょう。具体的には、/usersのindexページをブラウザで開くという典型的な操作を行うときに何が起こっているかをMVC (図2.11) を使って説明します。

mvc_detailed
図2.11RailsにおけるMVC。(拡大)
  1. ブラウザは/usersというURLへのリクエストを発行する。
  2. Railsは/usersをUsersコントローラ内のindexアクションに割り当てる (ルーティング)。
  3. indexアクションはUserモデルに「すべてのユーザーを取り出せ」と指示する (User.all)。
  4. Userモデルはすべてのユーザーをデータベースから取り出す。
  5. Userモデルはユーザーの一覧をコントローラに返す。
  6. コントローラはユーザーの一覧を@users変数に保存し、indexビューに渡す。
  7. ビューは、その中に埋め込まれているRubyを使用してHTMLを生成する。
  8. コントローラは、生成されたHTMLをブラウザに返す3

最初にブラウザからのリクエストを見てみましょう。このリクエストは、アドレスバーにURLを入力したりリンクをクリックした時に発生します (図2.11の1)。リクエストはRailsルーターに到達し (2)、ここでURL (とリクエストの種類: コラム3.3参照) に基づいて適切なコントローラのアクションに割り当てられます (ディスパッチ)。ユーザーのURLをUsersリソースで使用するコントローラアクションに割り当てる (マッピングする) ためのコードはリスト2.2です。このコードは、URLとアクションの組み合わせ (表2.1) を効率的に作成します。(:usersという一見奇妙な記法は、シンボルと呼ばれるものです。詳細については4.3.3で説明します。)

リスト2.2 Railsルートで使用するUsersリソース用のルール。
config/routes.rb
DemoApp::Application.routes.draw do
  resources :users
  .
  .
  .
end

2.2.1以降で紹介した各ページは、Usersコントローラの中にあるアクションにそれぞれ対応しています。1つのコントローラには関連する多数のアクションがまとめられています。リスト2.3は、scaffoldで生成したコントローラの骨格です。class UsersController < ApplicationControllerという記法は、Rubyのクラスでの継承の使用例となっていることにも注目してください (継承の概略については2.3.4、詳細については4.4で説明します)。

リスト2.3 Usersコントローラの骨格。
app/controllers/users_controller.rb
class UsersController < ApplicationController
.
.
.

  def index
    .
    .
    .
  end

  def show
    .
    .
    .
  end

  def new
    .
    .
    .
  end

  def create
    .
    .
    .
  end

  def edit
    .
    .
    .
  end

  def update
    .
    .
    .
  end

  def destroy
    .
    .
    .
  end
end

ページの数よりもアクションの数の方が多いことにお気付きでしょうか。indexshowneweditアクションはいずれも2.2.1のページに対応していますが、それ以外にもcreateupdatedestroyアクションがあります。通常、これらのアクションは、ページを出力せずにデータベース上のユーザー情報を操作します (もちろん、ページを出力しても良いのですが)。表2.2は、RailsにおけるRESTアーキテクチャ (コラム2.2) を構成するすべてのアクションの一覧です。RESTは、コンピュータ科学者Roy Fielding4によって提唱された「REpresentational State Transfer」という概念に基づいています。表2.2のURLには重複しているものがあることに注目してください。たとえば、showアクションと updateアクションは、どちらも/users/1というURLに対応しています。これらのアクション同士の違いは、それらのアクションに対応するHTTP requestメソッドの違いでもあります。HTTP requestメソッドの詳細については3.2.1で説明します。

HTTPリクエストURLアクション用途
GET/usersindexすべてのユーザーを表示するページ
GET/users/1showid=1のユーザーを表示するページ
GET/users/newnewユーザーを新規作成するページ
POST/userscreateユーザーを作成するアクション
GET/users/1/editeditid=1のユーザーを編集するページ
PATCH/users/1updateid=1のユーザーを更新するアクション
DELETE/users/1destroyid=1のユーザーを削除するアクション
表2.2リスト2.2のUsersリソースに含まれるRESTfulなルーティング

UsersコントローラとUserモデルの関係をさらに考察するために、indexアクションを整理してみました (リスト2.4) (scaffoldで自動生成されるコードは冗長で紛らわしいので除いてあります)。

リスト2.4 デモアプリケーションのユーザーindexアクションを整理したもの。
app/controllers/users_controller.rb
class UsersController < ApplicationController
.
.
.

  def index
    @users = User.all
  end
  .
  .
  .
end

indexアクションに@users = User.allという行があります (図2.11 の③に相当)。これによって、Userモデルからすべてのユーザーの一覧を取り出し (④)、@usersという変数に保存します (⑤)。なお、@usersは「あっと ゆーざーず」と発音します。Userモデルの内容はリスト2.5にあります。驚くほどシンプルな内容ですが、継承 (2.3.4および4.4) によって多くの機能が備わっています。特に、Active RecordというRubyライブラリのおかげで、リスト2.5のUserモデルはUser.allというリクエストに対してすべてのユーザーを返すことができます。

リスト2.5 デモアプリケーションのUserモデル。
app/models/user.rb
class User < ActiveRecord::Base
end

@users変数にユーザー一覧が保存されると、コントローラはリスト2.6ビューを呼び出します (⑥)。@記号で始まる変数はRubyではインスタンス変数と呼ばれます。ビューでは自動的にこれらのインスタンス変数を使用できます。この場合、リスト2.6index.html.erbビューは、@usersの一覧を並べ、1行ごとにHTMLの行として出力します (今はこのコードの意味がわからなくても問題ありません。これはあくまで説明のためのものです)。

リスト2.6 ユーザーのindexのビュー。
app/views/users/index.html.erb
<h1>Listing users</h1>

<table>
  <tr>
    <th>Name</th>
    <th>Email</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @users.each do |user| %>
  <tr>
    <td><%= user.name %></td>
    <td><%= user.email %></td>
    <td><%= link_to 'Show', user %></td>
    <td><%= link_to 'Edit', edit_user_path(user) %></td>
    <td><%= link_to 'Destroy', user, method: :delete,
                                     data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New User', new_user_path %>

ビューはその内容をHTMLに変換し (⑦)、コントローラがブラウザにHTMLを送信して、ブラウザでHTMLが表示されます (⑧)。

2.2.3Users リソースの欠点

scaffoldで作成したUsersリソースは、Railsの概要を手っ取り早く説明するには良いのですが、以下のようなさまざまな問題点を抱えています。

  • データの検証が行われていない。 このままでは、ユーザー名が空欄であったり、でたらめなメールアドレスを入力したりしても通ってしまいます。
  • ユーザー認証が行われていない。 サインイン、サインアウトが行われていないので、誰でも無制限に操作できてしまいます。
  • テストが行われていない。 厳密にはこれは正しい表現ではありません。というのも、scaffoldのコードには初歩的なテストが一応含まれているからです。ただ、scaffoldのテストコードは読みづらく、柔軟性もありません。さらにデータの検証、ユーザー認証、その他に必要な独自テストも含まれていません。
  • レイアウトが整えられていない。 サイトデザインも操作法も一貫していません。
  • 理解が困難。 scaffoldのコードを理解できるぐらいなら、そもそも本書を読む必要はないでしょう。

2.3Microposts リソース

Usersリソースを生成して内容を理解しましたので、今度はMicropostsリソースで同じことをやってみましょう。なお、この節全体について、Micropostsリソースを理解する際には2.2のuser要素と比較しながら進めることをお勧めします。実際、これらの2つのリソースはさまざまな面で似通っています。RailsのRESTful構造を身体に叩きこむには、繰り返し学ぶのが一番です。UsersリソースとMicropostsリソースの構造の類似点を理解することが、この章の主要な目的です (もちろん、この章のような初歩的なサンプルアプリケーションではない、頑丈なアプリケーションを開発するのは簡単ではありません。Micropostsリソースについては第10章で再び取り扱いますが、その頃にはMicropostsは作り込みが進んで外観がすっかり変わってしまいます)。

2.3.1マイクロポストのページを表示する

Usersリソースの場合と同様に、Micropostsリソースもscaffoldでコードを生成してみましょう。rails generate scaffoldコマンドを使用して、図2.3のデータモデルを実装してみます5

$ rails generate scaffold Micropost content:string user_id:integer
      invoke  active_record
      create    db/migrate/20130307005528_create_microposts.rb
      create    app/models/micropost.rb
      invoke      test_unit
      create      test/models/micropost_test.rb
      create      test/fixtures/microposts.yml
      invoke  resource_route
       route  resources :microposts
      invoke  jbuilder_scaffold_controller
      create    app/controllers/microposts_controller.rb
      invoke    erb
      create      app/views/microposts
      create      app/views/microposts/index.html.erb
      create      app/views/microposts/edit.html.erb
      create      app/views/microposts/show.html.erb
      create      app/views/microposts/new.html.erb
      create      app/views/microposts/_form.html.erb
      invoke      test_unit
      create      test/controllers/microposts_controller_test.rb
      invoke  helper
      create      app/helpers/microposts_helper.rb
      invoke      test_unit
      create        test/helpers/microposts_helper_test.rb
      invoke    jbuilder
       exist      app/views/microposts
      create      app/views/microposts/index.json.jbuilder
      create      app/views/microposts/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/microposts.js.coffee
      invoke    scss
      create      app/assets/stylesheets/microposts.css.scss
      invoke  scss
   identical    app/assets/stylesheets/scaffolds.css.scss

新しいデータモデルでデータベースを更新するには、2.2のときと同様にマイグレーションを実行します。

$ bundle exec rake db:migrate
==  CreateMicroposts: migrating =============================
-- create_table(:microposts)
   -> 0.0023s
==  CreateMicroposts: migrated (0.0026s) ======================

これでMicropostsを作成する準備ができました。作成方法は2.2.1と同じです。Railsのroutesファイルは期待どおりにscaffoldジェネレータによって更新され、リスト2.7のようにMicropostsリソース用のルールが追加されました6。ユーザーの場合と同様、resources :micropostsというルーティングルールは、表2.3に示したようにマイクロポスト用のURLをMicropostsコントローラ内のアクションに割り当てます。

リスト2.7 Micropostsリソース用のルールが追加されたRailsのroutesファイル。
config/routes.rb
DemoApp::Application.routes.draw do
  resources :microposts
  resources :users
  .
  .
  .
end
HTTPリクエストURLアクション用途
GET/micropostsindexすべてのマイクロポストを表示するページ
GET/microposts/1showid=1のマイクロポストを表示するページ
GET/microposts/newnewマイクロポストを新規作成するページ
POST/micropostscreateマイクロポストを新規作成するアクション
GET/microposts/1/editeditid=1のマイクロポストを編集するページ
PATCH/microposts/1updateid=1のマイクロポストを更新するアクション
DELETE/microposts/1destroyid=1のマイクロポストを削除するアクション
表2.3リスト2.7のMicropostsリソースに含まれるRESTfulなルーティング

Micropostsコントローラ自体の構造をリスト2.8に示します。リスト2.8の内容は、UsersControllerMicropostsControllerに置き換わっているだけで、リスト2.3完全に同一である点に注目してください。これは、RESTアーキテクチャが2つのリソースに同じように反映されていることを示しています。

リスト2.8 Micropostsコントローラの骨格。
app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController
.
.
.

  def index
    .
    .
    .
  end

  def show
    .
    .
    .
  end

  def new
    .
    .
    .
  end

  def create
    .
    .
    .
  end

  def edit
    .
    .
    .
  end

  def update
    .
    .
    .
  end

  def destroy
    .
    .
    .
  end
end

/microposts/newページをブラウザで開き、新しいマイクロポストの情報を入力してマイクロポストをいくつか作成してみましょう (図2.12)。

demo_new_micropost_rails_3
図2.12新しいマイクロポストの作成ページ (/microposts/new)。(拡大)

ここではひとまずマイクロポストを1つか2つ作成し、少なくとも片方のuser_id1になるようにして、2.2.1で作成した最初のユーザーのidと同じにします。結果は図2.13のようになるはずです。

demo_micropost_index_rails_3
図2.13マイクロポストのindexページ (/microposts)。(拡大)

2.3.2マイクロポストをマイクロにする

マイクロポストのマイクロという名前にふさわしく、何らかの方法で文字数制限を与えてみましょう。Railsでは、検証 (validates) を使用して簡単にこのような入力制限を追加することができます。Twitterのように140文字の制限を与えるには、lengthを指定します。テキストエディタかIDEを使用してapp/models/micropost.rbを開き、 リスト2.9の内容に置き換えます。(注: リスト2.9のようなvalidatesはRails 3の機能です。Rails 2.3の場合は validates_length_ofを使用します。)

リスト2.9 マイクロポストの最大文字数を140文字に制限する。
app/models/micropost.rb
class Micropost < ActiveRecord::Base
  validates :content, length: { maximum: 140 }
end

リスト2.9のコードは、これで本当に動作するのかと思えるかもしれませんが、ちゃんと動作します (検証機能については6.2でさらに詳しく説明します)。141文字以上の新規マイクロポストを投稿してみればわかります。図2.14に示したとおり、マイクロポストの内容が長すぎるというエラーメッセージがRailsによって表示されます (エラーメッセージの詳細については7.3.3で説明します)。

micropost_length_error_rails_3
図2.14マイクロポストの作成に失敗した場合のエラーメッセージ。(拡大)

2.3.3ユーザーとマイクロポストをhas_manyで関連づける

異なるデータモデル同士の関連付けは、Railsの強力な機能です。ここでは、1人のユーザーに対し複数のマイクロポストがあるとしましょう。UserモデルとMicropostモデルをそれぞれリスト2.10リスト2.11のように更新することでこの関連付けを表現できます。

リスト2.10 1人のユーザーに複数のマイクロポストがある。
app/models/user.rb
class User < ActiveRecord::Base
  has_many :microposts
end
リスト2.11 1つのマイクロポストは1人のユーザーにのみ属する。
app/models/micropost.rb
class Micropost < ActiveRecord::Base
  belongs_to :user
  validates :content, length: { maximum: 140 }
end

この関連付けを図で表したものが図2.15です。micropostsテーブルにはuser_idカラムを作成してあったので、それによってRailsとActive Recordがマイクロポストとユーザーを関連付けることができるようになっています。

micropost_user_association
図2.15マイクロポストとユーザーの関連付け。

第10章第11章では、関連付けられたユーザーとマイクロポストを同時に表示し、Twitterのようなマイクロポストのフィードを作成する予定です。ここでは、Railsのconsoleを使用して、ユーザーとマイクロポストの関連付けを確認するにとどめます。Railsのconsoleは、Railsアプリケーションを対話的に操作することができる便利なツールです。まず、ターミナルでrails consoleコマンドを入力します。続いて、User.firstを使用してデータベースから1人目のユーザーの情報を取り出し、first_user変数に保存します7

$ rails console
>> first_user = User.first
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.org",
created_at: "2013-03-06 02:01:31", updated_at: "2013-03-06 02:01:31">
>> first_user.microposts
=> [#<Micropost id: 1, content: "First micropost!", user_id: 1, 
created_at: "2011-11-03 02:37:37", updated_at: "2011-11-03 02:37:37">, 
"2013-03-06 02:37:37", updated_at: "2013-03-06 02:37:37">,
#<Micropost id: 2,content: "Second micropost", user_id: 1, 
created_at: "2013-03-06 02:38:54",updated_at: "2013-03-06 02:38:54">]
>> exit

(最後の行のようにexitを実行するとrails consoleを終了できます。多くのシステムでは、Ctrl-dキーを押して終了することもできます。) first_user.micropostsというコードを実行すると、そのユーザーに関連付けられているマイクロポストにアクセスできます。このときActive Recordは、user_idfirst_userのid (ここでは1) と等しいマイクロポストを自動的に返します。Active Recordの関連付け機能については第10章第11章でさらに詳しく解説します。

2.3.4継承の階層

最後に、デモアプリケーションで使用しているRailsのコントローラとモデルのクラス階層について簡単に解説します。この節を理解するには、多少なりともオブジェクト指向プログラミング (OOP) の経験が必要です。オブジェクト指向プログラミングを学んだことのない方はこの節をスキップしても構いません。特に、クラスの概念 (4.4で解説します) に慣れていない方は、後でこの節をもう一度読み返してください。

最初に、モデルの継承構造について説明します。リスト2.12リスト2.13を比較してみると、UserモデルとMicropostモデルはいずれもActiveRecord::Baseというクラスを継承しています (継承関係は<記号で表現されています)。このクラスは、ActiveRecordが提供するベースクラスであり、クラス間のリレーションは図2.16のようになります。ActiveRecord::Baseクラスを継承したことによって、作成したモデルオブジェクトはデータベースにアクセスできるようになり、データベースのカラムをあたかもRubyの属性のように扱えるようになります。

リスト2.12 Userクラスにおける継承。
app/models/user.rb
class User < ActiveRecord::Base
  .
  .
  .
end
リスト2.13 Micropostクラスにおける継承。
app/models/micropost.rb
class Micropost < ActiveRecord::Base
  .
  .
  .
end
demo_model_inheritance
図2.16UserモデルとMicropostモデルの継承階層。

コントローラの継承構造はもう少しだけ複雑です。リスト2.14リスト2.15を比較してみると、UsersコントローラとMicropostsコントローラはいずれもApplicationControllerを継承しています。リスト2.16を見ると、ApplicationController自身はActionController::Baseを継承しています。これはRailsのAction Packというライブラリが提供している、コントローラ用のベースクラスです。これらのクラス同士の関係を図2.17に示します。

リスト2.14 UsersControllerクラスにおける継承。
app/controllers/users_controller.rb
class UsersController < ApplicationController
  .
  .
  .
end
リスト2.15 MicropostsControllerクラスにおける継承。
app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController
  .
  .
  .
end
リスト2.16 ApplicationControllerクラスにおける継承。
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  .
  .
  .
end
demo_controller_inheritance
図2.17UsersコントローラとMicropostsコントローラにおける継承関係。

モデルの継承関係と同様に、UsersコントローラもMicropostsコントローラも最終的にはActionController::Baseを継承しており、モデルオブジェクトの操作、インバウンドHTTP requestのフィルタ、ビューをHTMLとして出力するなどの多彩な機能を実行できるようになっています。Railsのコントローラは必ずApplicationControllerを継承しているので、Applicationコントローラで定義されたルールは自動的にアプリケーションのすべてのアクションに反映されます。たとえば8.2.1では、サンプルアプリケーションのすべてのコントローラにサインインとサインアウト用のヘルパーを含めています。

2.3.5デモアプリケーションのデプロイ

Micropostsリソースの説明が終わりましたので、ここでリポジトリをGitHubに登録しましょう。

$ git add .
$ git commit -m "Finish demo app"
$ git push

通常は、更新をあまりためないように、Gitのコミットをなるべく頻繁に行うことが望ましいのですが、この章の締めくくりとしてサイズの大きなコミットを1度だけ行っても問題ありません。

この時点で、デモアプリケーションを1.4のようにHerokuにデプロイしてもかまいません。

$ heroku create
$ git push heroku master

アプリケーションのデータベースが動作するようにするには、以下を実行して本番データベースのマイグレーションを行う必要もあります。

$ heroku run rake db:migrate

このコマンドを実行すると、Heroku上のデータベースが、ユーザーとマイクロポストのデータモデルで更新されます。

2.4最後に

ついにRailsアプリケーションを最後まで完成させました。この章で作成したデモアプリケーションには良いところもありますが、さまざまな弱点もあります。

良い点

  • Rails全体を高度なレベルで概観できた
  • MVCモデルを紹介できた
  • RESTアーキテクチャに初めて触れた
  • データモデルの作成を初めて行った
  • データベースを背後に持つWebアプリケーションを本番環境で動かした

課題

  • レイアウトやスタイルが皆無
  • “Home” や “About” のような静的なページがない
  • ユーザーにパスワードを設定できない
  • ユーザーの画像も置けない
  • サインインできない
  • セキュリティがない
  • ユーザーとマイクロポストを自動的に関連付けていない
  • “following” 機能も “followed” 機能もない
  • マイクロポストをフィードできない
  • テスト駆動開発が行われていない
  • 理解が困難

本書では以後、良い点を保ちつつこれらの弱点を克服していきます。

  1. もっと多い文字数の投稿できるモデルにしたい場合は (たとえば、マイクロポストではなく、ブログのような投稿を許可したい場合は)、stringの代わりにtextを使うとよいでしょう。
  2. scaffoldにおける命名は、モデル名の命名の習慣に従っています。リソースやコントローラは複数形で表し、モデルは単数形で表すのが普通です。UsersではなくUserとしたのはこのためです。
  3. ビューは、(ApacheやNginxなどのWebサーバーを経由してはいるが) ブラウザにHTMLを直接返すと説明している文献もあります。私は、Railsの実際の実装とは無関係に、コントローラを情報の流れの中心となるハブとみなすことを好んでいます。
  4. Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral dissertation, University of California, Irvine, 2000. 
  5. ユーザーでscaffoldを実行した場合と同様に、scaffoldジェネレータはマイクロポストでもRailsモデルを単数形とする習慣に従います。実行したコマンドがgenerate Micropostと単数形になっていたのはこのためです。
  6. scaffoldで生成したコードにはリスト2.7よりも多くの改行が追加されます。Rubyは単なる改行を無視するので、問題はありません。
  7. 実際のターミナル上では、プロンプトがruby-2.0.0-head >などと表示される可能性がありますが、Rubyのバージョンが環境によって異なる可能性があるため、例のプロンプトは>>と表記しています。
Railsチュートリアルは,Ruby/Rails のアジャイル開発を得意とする YassLab によって運営・保守されております.
継続的に良いコンテンツを提供する為に,電子書籍スクリーンキャストのご購入を検討して頂けると幸いです m(_ _)m
スポンサーシップや商用利用などに関するご相談がありましたら,お問い合わせページよりお気軽にご連絡ください :)