Rails tutorial　第6版　第3章学習メモ

第3章　ほぼ静的なページの作成

Cloud9のコンソールubuntu:~/environment $ の後に下記コマンドでアプリ作成

`$ rails _6.0.3_ new sample_app`
![新しいビットマップ イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933665/3befc1f5-0cb0-95b5-ba47-028d9aa3d00a.jpeg)

作成したsample appディレクトリへ下記コマンドで移動

`$ cd sample_app`

サンプルアプリケーション用のGemfileを編集する

Sample_appディレクトリ内にあるGemfileを開いて下記のように編集する

:::note

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

gem 'rails',      '6.0.3'
gem 'puma',       '4.3.6'
gem 'sass-rails', '5.1.0'
gem 'webpacker',  '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder',   '2.9.1'
gem 'bootsnap',   '1.4.5', require: false

group :development, :test do
  gem 'sqlite3', '1.4.1'
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console',           '4.0.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.1.0'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'capybara',                 '3.28.0'
  gem 'selenium-webdriver',       '3.142.4'
  gem 'webdrivers',               '4.1.2'
  gem 'rails-controller-testing', '1.0.4'
  gem 'minitest',                 '5.11.3'
  gem 'minitest-reporters',       '1.3.8'
  gem 'guard',                    '2.16.2'
  gem 'guard-minitest',           '2.4.6'
end

group :production do
  gem 'pg', '1.1.4'
end

# Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
:::

Gemfileで指定したgemのインストールをする、ただし、--without productionオプションを使い、production環境でしか使わないgemはインストールしないようにする。

`$ bundle install --without production`

上記コマンド入力後bundle updateを実行する

ここまで出来たらGitリポジトリを初期化する

`$ git init`初期化
`$ git add -A`追加
`$ git commit -m "Initialize repository"`コメント


サンプルアプリケーション向けにREADME.mdファイルを下記の通り書き換える

::: note
# Ruby on Rails チュートリアルのサンプルアプリケーション

これは、次の教材で作られたサンプルアプリケーションです。
[*Ruby on Rails チュートリアル*](https://railstutorial.jp/)
（第6版）
[Michael Hartl](https://www.michaelhartl.com/) 著

## ライセンス

[Ruby on Rails チュートリアル](https://railstutorial.jp/)内にある
ソースコードはMITライセンスとBeerwareライセンスのもとで公開されています。
詳細は [LICENSE.md](LICENSE.md) をご覧ください。

## 使い方

このアプリケーションを動かす場合は、まずはリポジトリを手元にクローンしてください。
その後、次のコマンドで必要になる RubyGems をインストールします。

```
$ bundle install --without production
```

その後、データベースへのマイグレーションを実行します。

```
$ rails db:migrate
```

最後に、テストを実行してうまく動いているかどうか確認してください。

```
$ rails test
```

テストが無事に通ったら、Railsサーバーを立ち上げる準備が整っているはずです。

```
$ rails server
```

詳しくは、[*Ruby on Rails チュートリアル*](https://railstutorial.jp/)
を参考にしてください。
:::

書き終えたら変更をコミットする

`$ git commit -am "Improve the README`

ここまでをGitHub上にリポジトリを作成し、リモートにもpushする。

`$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/sample_app.git`

`$ git push -u origin master`

`Username for 'https://github.com/mizumanjyu/sample_app.git':`
と表示されるので文字通りgithubのUsernameを入力しエンター、次に
`Password for 'https://mizumanjyu@github.com/mizumanjyu/sample_app.git': `
と表示されるので、githubのパスワードを入力、今現在パスワードではなく、トークンを作成し入力する、この時入力しても何も表示されないが確かに入力されているのでエンターを押すとpushされる。


Cloud9への接続を許可するためにconfig/environments/development.rbの内容を編集する。

::: note

Rails.application.configure do
  .
  .
  .
  # Cloud9 への接続を許可する
  config.hosts.clear
end
:::

後でProduction環境にプッシュしたときに悩まないよう、作成したアプリを早い段階で本番環境であるHerokuへデプロイしておくと良い、しかしデプロイしても現段階のデータ内容では確認しにくいのでhelloアクションを作成しApplicationコントローラに追加してみる。
`app/controllers/application_controller.rb`

:::note
class ApplicationController < ActionController::Base

  def hello
    render html: "hello, world!"
  end
end

:::

ルートルーティングを設定

`config/routes.rb`

:::note
Rails.application.routes.draw do
  root 'application#hello'
end
:::

ここまでの変更をコミットしてGitHubとHerokuへプッシュする

:::note
$ git commit -am "Add hello"
$ git push
$ heroku create
$ git push heroku master
:::

:::note
$ heroku logs         # 直近のイベントを表示する
$ heroku logs --tail  # イベント発生のたびに自動表示する（Ctrl-Cで終了）
:::

演習
1.Markdown記法のREADME（リスト 3.3）がHTMLとして正しくGitHub上で描画されているか、確認してみてください。

pushしてあるGitHubのリポジトリにある当該アプリを開くと編集されたREADME.mdファイルが確認できる。

2.本番環境（Heroku）のルートURLにアクセスして、デプロイが成功したかどうか確かめてみてください。

HerokuのアプリからOpenAppを開くとデプロイしてるかどうか下記の通り確認できる。はず。

![新しいビットマップ イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933665/92635d3c-2ffd-e6a1-d6db-08d489026c64.jpeg)

Gitを使う場合、masterブランチで作業するのではなく、その都度トピックブランチを作成して作業するのが良い習慣らしい。なので静的なページ用のトピックブランチをチェックアウトする。

```ruby:qiita.rb
$ git checkout -b static-pages
```

静的なページの生成

コントローラ名は「Static Pages」に決め、表記をキャメルケースのStaticPagesにし、Homeページ、Helpページ、Aboutページ、に使うアクションもそれぞれ作成することにして、アクション名はすべて小文字のhome、help、aboutにする。generateスクリプトではアクション名をまとめて指定することもできるので、HomeページとHelpページ用のアクションでは作成せず、この先の学習のため、あえてコマンドラインでは作成しない。

`$ rails generate controller StaticPages home help`

この時点で上記コマンドを入力したら下記の様なエラーが発生

:::note
ubuntu:~/environment/sample_app (static-pages) $ rails generate controller StaticPages home help
warning Integrity check: System parameters don't match                                                                                             
error Integrity check failed                                                                                                                       
error Found 1 errors.                                                                                                                              


========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================


To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).


yarn check v1.22.5
info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.

:::

なので、上記にあるように下記コマンドを実行

`yarn install --check-files`

改めて下記コマンドを入力するとコントローラが作成完了する。

`$ rails generate controller StaticPages home help`

![新しいビットマップ イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933665/b41cd106-ab0c-1a9f-c66c-449466fcb150.jpeg)

次に進む前にGitリポジトリに追加しておく

:::note
$ git add -A
$ git commit -m "Add a Static Pages controller"
$ git push -u origin static-pages
:::

もとに戻す方法

例:コントローラ自動作成と取り消し処理のコマンド

:::note
  $ rails generate controller StaticPages home help
  $ rails destroy  controller StaticPages home help
:::

例：マイグレーションの変更を元に戻す方法

:::note
$ rails db:migrate

元に戻したいときは db:rollbackで一つ前に戻す。

$ rails db:rollback

最初の状態に戻したいときは、 VERSION=0オプションを使う。

$ rails db:migrate VERSION=0

:::

StaticPagesコントローラを生成すると、（config/routes.rb）ファイルが自動的に更新される。

今回はStaticPagesコントローラ内にhomeアクションを追加したので/static_pages/homeにアクセスするとページを取得(GET)できるようになっているので、rails serverを起動するとプレビューで確認できる。

`$ rails server`

演習
1.Fooというコントローラを作成し、その中にbarとbazアクションを追加してみてください。

`$ rails generate controller Foo bar baz`で作成される

2.コラム3.1で紹介したテクニックを駆使して、Fooコントローラとそれに関連するアクションを削除してください。
ターミナルは一度実行したコマンドを上下カーソルで呼び出せので、先ほど作成時に実行したコマンドのgenerateをdestroyに変更して実行すれば削除される。

`rails destroy controller Foo bar baz`


静的なページの調整
HomeページのHTMLを修正する
`app/views/static_pages/home.html.erb`

``` static_pages/home.html.erb
<h1>Sample App</h1>
<p>
  This is the home page for the
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  sample application.
</p>
```

HelpページのHTMLを修正する
`app/views/static_pages/help.html.erb`

``` static_pages/help.html.erb
<h1>Help</h1>
<p>
  Get help on the Ruby on Rails Tutorial at the
  <a href="https://railstutorial.jp/help">Rails Tutorial help page</a>.
  To get help on this sample app, see the
  <a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em>
  book</a>.
</p>
```

###テストから始める###

今度はあえてgenerateで作成しなかったAboutページを追加する。
何らかの変更を行う際には、常に「自動化テスト」を作成して昨日が正しく実装されたか確認する習慣を身に付けることが必須。アプリケーションを開発しながらテストスイート（Test Suite）をみっちり作成しておけば、いざというときのセーフティネットにもなる。それ自体が実行可能なドキュメントにもなる。

###最初のテスト###

```
$ ls test/controllers/
static_pages_controller_test.rb
```

StaticPagesコントローラのデフォルトのテスト　GREEN
`test/controllers/static_pages_controller_test.rb`

```
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  test "should get home" do
    get static_pages_home_url
    assert_response :success
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
  end
end
```

```
test "should get home" do
  get static_pages_home_url
  assert_response :success
end
```

上記を言葉で表すと「Homeページのテスト。GETリクエストをhomeアクションに対して発行（＝送信）せよ。そうすれば、リクエストに対するレスポンスは[成功]になるはず」という意味。

テストを書くサイクルに入る前に、今現在あるテストスイートをそのまま実行してみる。問題なくパスすることを確認する。下記railsコマンド

```
$ rails db:migrate     # システムによっては必要
$ rails test
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
```

###Red###

テスト駆動開発のサイクルは「失敗するテストを最初に書く」「次にアプリケーションのコードを書いて成功させる（パスさせる）」「必要ならリファクタリングする」のように進める。

最初のサイクルはAboutページ用の失敗するテストを書く。

AboutページのテストRED
`test/controllers/static_pages_controller_test.rb`

```
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  test "should get home" do
    get static_pages_home_url
    assert_response :success
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
  end
end
```

上記の通りaboutページのテストを先に作成しただけだとテストは予定通り1 errorsとなる。

`RED`

```
$ rails test
3 tests, 2 assertions, 0 failures, 1 errors, 0 skips
```

###about用のルートを追加するRED###

`config/routes.rb`

```
Rails.application.routes.draw do
  get  'static_pages/home'
  get  'static_pages/help'
  get  'static_pages/about'
  root 'application#hello'
end
```

###aboutアクションが追加されたStaticPagesコントローラRED###

`app/controllers/static_pages_controller.rb`

```
class StaticPagesController < ApplicationController

  def home
  end

  def help
  end

  def about
  end
end
```

エラー内容

```
ActionController::MissingExactTemplate:         ActionController::MissingExactTemplate: StaticPagesController#about is missing a template for request formats: text/html
```

今度のエラー内容はテンプレートが無い、Railsでは、テンプレートは「ビュー」を指す。app/views/static_pagesディレクトリに、about.html.erbを作る。

`$ touch app/views/static_pages/about.html.erb`

###AboutページのコードGREEN###

`app/views/static_pages/about.html.erb`

```
<h1>About</h1>
<p>
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  is a <a href="https://railstutorial.jp/#ebook">book</a> and
  <a href="https://railstutorial.jp/screencast">screencast</a>
  to teach web development with
  <a href="https://rubyonrails.org/">Ruby on Rails</a>.
  This is the sample application for the tutorial.
</p>
```

###少しだけ動的なページ###


ここの目標は　Homeページ、Helpページ、Aboutページをそれぞれ編集して、最終的にページごとに異なるタイトルを表示する。ここでは<title>タグの内容を変更する。

rails newコマンドを実行すると、レイアウトも自動的にデフォルトで作成されているので一時的にapplication.html.erbファイルの名前をlayout_fileに変更する

`$ mv app/views/layouts/application.html.erb layout_file`

###StaticPagesコントローラのタイトルをテストするRED###
`test/controllers/static_pages_controller_test.rb`

```
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
  end
end
```

この時点でテストを実行しても各ページの<title>タグ内に指定された文字列が入ってないのでREDになる予定。

`RED`

```
$ ubuntu:~/environment/sample_app (static-pages) $ rails test
3 tests, 6 assertions, 3 failures, 0 errors, 0 skip
```
###タイトルを追加する(Green)###

###完全なHTML構造を備えたHomeページのビューRED###
`app/views/static_pages/home.html.erb`

```
<!DOCTYPE html>
<html>
  <head>
    <title>Home | Ruby on Rails Tutorial Sample App</title>
  </head>
  <body>
    <h1>Sample App</h1>
    <p>
      This is the home page for the
      <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
      sample application.
    </p>
  </body>
</html>
```
###完全なHTML構造を備えたHelpページのビューRED###
`app/views/static_pages/help.html.erb`

```
<!DOCTYPE html>
<html>
  <head>
    <title>Help | Ruby on Rails Tutorial Sample App</title>
  </head>
  <body>
    <h1>Help</h1>
    <p>
      Get help on the Ruby on Rails Tutorial at the
      <a href="https://railstutorial.jp/help">Rails Tutorial help
      page</a>.
      To get help on this sample app, see the
      <a href="https://railstutorial.jp/#ebook">
      <em>Ruby on Rails Tutorial</em> book</a>.
    </p>
  </body>
</html>
```

###完全なHTML構造を備えたAboutページのビューRED###
`app/views/static_pages/about.html.erb`

```
<!DOCTYPE html>
<html>
  <head>
    <title>About | Ruby on Rails Tutorial Sample App</title>
  </head>
  <body>
    <h1>About</h1>
    <p>
      <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
      is a <a href="https://railstutorial.jp/#ebook">book</a> and
      <a href="https://railstutorial.jp/screencast">screencast</a>
      to teach web development with
      <a href="https://rubyonrails.org/">Ruby on Rails</a>.
      This is the sample application for the tutorial.
    </p>
  </body>
</html>
```

以上、テストで指定した３つのページの<title>タグ内に文字列を追加したのでテストではGREENになるはず。

```
Finished in 0.05352s
3 tests, 6 assertions, 0 failures, 0 errors, 0 skip
```
なった。

###演習###
1.StatcPagesコントローラのテストには繰り返しがあった。特に「Ruby on Rails Tutorial Sample App」と言う基本タイトルは各テストで毎回同じ内容を書いてしまってる。そこでsetupと言う特別なメソッド（各テストが実行される直前で実行されるメソッド）を使って、この問題を解決。

###基本タイトルを使ったStaticPagesコントローラのテストGREEN###
`test/controllers/static_pages_controller_test.rb`

```

require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | #{@base_title}"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | #{@base_title}"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | #{@base_title}"
  end
end
```

上記、コピペせずにaboutページのコードのところ、#{base_title}として@忘れでエラーでた。すぐ解決したけど、ほんの些細な事でもエラーが出るのは良い。

###レイアウトと埋め込みRuby(Refactor)###

この節では、Railsコントローラとアクションを使って３つの有効なページを生成することで様々なことを達成した、しかし単純な静的ページである。またRailsの能力を十分に発揮できてないし、コードが甚だ重複している。

-ページのタイトルがどれもほとんど同じ
-「Ruby on Rails Tutorial Sample App」という文字が3つのタイトルで繰り返し使われてる。
-HTMLの構造全体が各ページで重複している
なので最初に若干のコードを追加して各ページのタイトルを完全に一致させる。

重複を取り除く1つとして、ビューで「埋め込みRuby」(Embedde Ruby)がつかえる。Home、Help、Aboutページには可変要素があるので、RubyのProvideメソッドを使ってタイトルをページごとに変更する。

###タイトルにERBを使ったHomeページのビューGREEN###

```app/views/static_pages/home.html.erb
<% provide(:title, "Home") %>
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
  </head>
  <body>
    <h1>Sample App</h1>
    <p>
      This is the home page for the
      <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
      sample application.
    </p>
  </body>
</html>
```

`<% provide(:title, "Home") %>`
上コードでは「<% ... %>」という記法が使われている。その中からRailsのProvideメソッドを呼び出している。メソッドの引数では、"Home"という文字列と:titleというラベルを関連付けている。そしてタイトルの部分では、上の記法と連携する「<%= ...%>」という似た記法を使い、その中でRubyのyieldメソッドを呼び出している。このメソッドで、テンプレートのその部分に実際のタイトルが挿入されます。

`<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>`

```
$rails test
```

こうしてみると、HTMLの構造はtitleタグの内容も含めてどのページも完全に同じ。異なる点はBodyタグの内側のコンテンツだけ。

続いて、HelpとAboutページも同様に変更する。

###タイトルにERBを使ったHelpページビューGREEN###

```ruby:app/views/static_pages/help.html.erb
<% provide(:title, "Help") %>
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
  </head>
  <body>
    <h1>Help</h1>
    <p>
      Get help on the Ruby on Rails Tutorial at the
      <a href="https://railstutorial.jp/help">Rails Tutorial help
      section</a>.
      To get help on this sample app, see the
      <a href="https://railstutorial.jp/#ebook">
      <em>Ruby on Rails Tutorial</em> book</a>.
    </p>
  </body>
</html>
```

###タイトルにERBを使ったAboutページのビューGREEN###

```ruby:app/views/static_pages/about.html.erb
<% provide(:title, "About") %>
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
  </head>
  <body>
    <h1>About</h1>
    <p>
      <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
      is a <a href="https://railstutorial.jp/#ebook">book</a> and
      <a href="https://railstutorial.jp/screencast">screencast</a>
      to teach web development with
      <a href="https://rubyonrails.org/">Ruby on Rails</a>.
      This is the sample application for the tutorial.
    </p>
  </body>
</html>
```

ここまで済んだらリファクタリングしてHTMLの重複した構造をDRYにするしかない、そのためにRailsにはapplication.html.erbという名前のレイアウトファイルがある。以前ファイル名を変えたものをもとに戻す。
`$ mv layout_file app/views/layouts/application.html.erb`

元に戻したファイル内の<title>タグの中を差し替える。

`<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>`

上記の用に変更したレイアウトファイルは下記の通り。

```ruby:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag    'application',
                               'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```

ここまででテストをパスしても、Html、Help、Aboutページの重複した箇所を修正する必要がある。

###HTML構造を削除したHomeページGREEN###

```ruby:app/views/static_pages/home.html.erb
<% provide(:title, "Home") %>
<h1>Sample App</h1>
<p>
  This is the home page for the
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  sample application.
</p>
```

###HTML構造を削除したHelpページGREEN###

```ruby:app/views/static_pages/help.html.erb
<% provide(:title, "Help") %>
<h1>Help</h1>
<p>
  Get help on the Ruby on Rails Tutorial at the
  <a href="https://railstutorial.jp/help">Rails Tutorial help page</a>.
  To get help on this sample app, see the
  <a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em>
  book</a>.
</p>
```

###HTML構造を削除したAboutページ###

```ruby:app/views/static_pages/about.html.erb
<% provide(:title, "About") %>
<h1>About</h1>
<p>
  <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
  is a <a href="https://railstutorial.jp/#ebook">book</a> and
  <a href="https://railstutorial.jp/screencast">screencast</a>
  to teach web development with
  <a href="https://rubyonrails.org/">Ruby on Rails</a>.
  This is the sample application for the tutorial.
</p>
```

上のように定義されたビューは、Home、Help、Aboutページの表示は以前とは変わりませんが、コードの重複が大きく削減された。

`GREEN`

```ruby
ubuntu:~/environment/sample_app (static-pages) $ rails test
Running via Spring preloader in process 10352
Started with run options --seed 16102

  3/3: [=======================================================================================================] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.06917s
3 tests, 6 assertions, 0 failures, 0 errors, 0 skips
```

###演習###
1.サンプルアプリケーションにContact（問い合わせ先）ページを作成してください15 。（ヒント: まずはリスト 3.16を参考にして、/static_pages/contactというURLのページに「Contact | Ruby on Rails Tutorial Sample App」というタイトルが存在するかどうかを確認するテストを最初に作成しましょう。次に、3.3.3でAboutページを作ったときのと同じように、Contactページにもリスト 3.41のコンテンツを表示してみましょう。）
###Contactページで使うコード###

```ruby:app/views/static_pages/contact.html.erb
<% provide(:title, "Contact") %>
<h1>Contact</h1>
<p>
  Contact the Ruby on Rails Tutorial about the sample app at the
  <a href="https://railstutorial.jp/contact">contact page</a>.
</p>
```
回答
/sample_app/test/controllers/static_pages_controller_test.rbにContactページのテストを作成する。

```
  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "contact | #{@base_title}"
  end
```

これだけだとコントローラーが無いとエラーが返る。
なのでコントローラにも追加。

```ruby:/sample_app/app/controllers/static_pages_controller.rb
/sample_app/app/controllers/static_pages_controller.rb
```

ここでtestしても同じことでした。なのでroutにもcontact追加。

```ruby:/sample_app/config/routes.rb
Rails.application.routes.draw do
  get 'static_pages/home'
  get 'static_pages/help'
  get  'static_pages/about'
  get 'static_pages/contact'
  root 'application#hello'
end
```

ここでtestすると下記エラー

```
ERROR["test_should_get_contact", #<Minitest::Reporters::Suite:0x00005612791b5a58 @name="StaticPagesControllerTest">, 1.1499366540001574]
 test_should_get_contact#StaticPagesControllerTest (1.15s)
ActionController::MissingExactTemplate:         ActionController::MissingExactTemplate: StaticPagesController#contact is missing a template for request formats: text/html
            test/controllers/static_pages_controller_test.rb:28:in `block in <class:StaticPagesControllerTest>'
```

MissingExactTemplate。Template=ビューファイルがない。なので作る

`$ touch app/views/static_pages/contact.html.erb`


できたcontactファイル内を上記の内容に編集する。

これでtestはGREENになる。

```
ubuntu:~/environment/sample_app (static-pages) $ rails test
Running via Spring preloader in process 11811
Started with run options --seed 60157

  4/4: [====] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.98530s
4 tests, 8 assertions, 0 failures, 0 errors, 0 skips
```

###ルーティングの設定###

サイトのカスタマイズが終わって、テストスイートも軌道にのってきたのでアプリケーションルートのルーティングを設定しておく。ルーティングを設定するのはroutes.rbファイルを編集してルート「/」とWebページを結びつける。結びつける相手はHomeページ。
`root 'application#hello`
を次のコードに書き換える
`root 'static_pages#home`

###HomeページをルートURLに設定する###

```ruby:config/routes.rb
Rails.application.routes.draw do
  root 'static_pages#home'
  get  'static_pages/home'
  get  'static_pages/help'
  get  'static_pages/about'
end
```
###演習###
1.リスト 3.42にrootルーティングを追加したことで、root_urlというRailsヘルパーが使えるようになりました（以前、static_pages_home_urlが使えるようになったときと同じです）。リスト 3.43のFILL_INと記された部分を置き換えて、rootルーティングのテストを書いてみてください。

回答
  test "should get root" do
    get root_url
    assert_response :success
  end

2.実はリスト 3.42のコードを書いていたので、先ほどの課題のテストは既に green になっているはずです。このような場合、テストを変更する前から成功していたのか、変更した後に成功するようになったのか、判断が難しいです。リスト 3.42のコードがテスト結果に影響を与えていることを確認するため、リスト 3.44のようにrootルーティングをコメントアウトして見て、 red になるかどうか確かめてみましょう（なおRubyのコメント機能については4.2で説明します）。最後に、コメントアウトした箇所を元に戻し（すなわちリスト 3.42に戻し）、テストが green になることを確認してみましょう。

回答　やってみたらTestは予想通りREDに

```
ERROR["test_should_get_root", #<Minitest::Reporters::Suite:0x00007f8ce89b5380 @name="StaticPagesControllerTest">, 0.020042755999838846]
 test_should_get_root#StaticPagesControllerTest (0.02s)
NameError:         NameError: undefined local variable or method `root_url' for #<StaticPagesControllerTest:0x00007f8ce8743f20>
            test/controllers/static_pages_controller_test.rb:10:in `block in <class:StaticPagesControllerTest>'
```

###最後に###


```
$ git add -A
$ git commit -m "Finish static pages"
```

次にトピックブランチからmasterブランチに移動しマージする。

```
$ git checkout master
$ git merge static-pages
```

きりの良いところでコードをリモートリポジトリにアップロード。
`git push`

またHerokuにデプロイ

```
$ rails test
$ git push heroku
```


###本章のまとめ###
* テスト駆動開発では「RED・GREEN・REFACTER」サイクルを繰り返す、これが漸く理解できたかな。

###高度なセットアップ###

成功／失敗の表示設定をする「minitest reporters」とファイルの変更を検出して必要なテストだけを自動実行してくれる「Guard」の２つ。

このセットアップはmasterブランチで行う必要があるので切り替える。

`$ git checkout master`

###minitest reporters###

gemファイルにminitest-reportersを追加するとクラウドIDE(cloud9など)のシステムでREDやGREENの表示がみえやすくなる。

###テストでREDやGREENを表示できうるようにする###

```ruby:test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
require "minitest/reporters"
Minitest::Reporters.use!

class ActiveSupport::TestCase
  # 特定のワーカーではテストをパラレル実行する
  parallelize(workers: :number_of_processors)

  # すべてのテストがアルファベット順に実行されるよう、
  #test/fixtures/*.ymlにあるすべてのfixtureをセットアップする
  fixtures :all

  # （すべてのテストで使うその他のヘルパーメソッドは省略）
end
```

###Guardによるテストの自動化###
rails testコマンドを使うとき、テストをしようとするたびにエディタからコマンドラインに移動して手動でコマンドを打ち込むのが面倒なのでGuardを使って自動化を実行させるようにする。
Guardはファイルシステムの変更を監視し、例えばstatic_pages_test.rbファイルなどを変更すると自動的に実行してくれるツール。
実はすでにGemfileでguard gemをアプリケーション内にとりこんでいるのであとは初期化をするだけで動かすことができる。

```
ubuntu:~/environment/sample_app (master) $ bundle exec guard init
12:30:42 - INFO - Writing new Guardfile to /home/ubuntu/environment/sample_app/Guardfile
12:30:42 - INFO - minitest guard added to Guardfile, feel free to edit it
```

統合テストとビューが更新されたら自動的に適切なテストが実行されるように生成されたGuardfileを編集する。

###カスタマイズしたGuardfile###

```ruby:Guardfile
# Guardのマッチング規則を定義
guard :minitest, spring: "bin/rails test", all_on_start: false do
  watch(%r{^test/(.*)/?(.*)_test\.rb$})
  watch('test/test_helper.rb') { 'test' }
  watch('config/routes.rb') { interface_tests }
  watch(%r{app/views/layouts/*}) { interface_tests }
  watch(%r{^app/models/(.*?)\.rb$}) do |matches|
    "test/models/#{matches[1]}_test.rb"
  end
  watch(%r{^app/controllers/(.*?)_controller\.rb$}) do |matches|
    resource_tests(matches[1])
  end
  watch(%r{^app/views/([^/]*?)/.*\.html\.erb$}) do |matches|
    ["test/controllers/#{matches[1]}_controller_test.rb"] +
    integration_tests(matches[1])
  end
  watch(%r{^app/helpers/(.*?)_helper\.rb$}) do |matches|
    integration_tests(matches[1])
  end
  watch('app/views/layouts/application.html.erb') do
    'test/integration/site_layout_test.rb'
  end
  watch('app/helpers/sessions_helper.rb') do
    integration_tests << 'test/helpers/sessions_helper_test.rb'
  end
  watch('app/controllers/sessions_controller.rb') do
    ['test/controllers/sessions_controller_test.rb',
     'test/integration/users_login_test.rb']
  end
  watch('app/controllers/account_activations_controller.rb') do
    'test/integration/users_signup_test.rb'
  end
  watch(%r{app/views/users/*}) do
    resource_tests('users') +
    ['test/integration/microposts_interface_test.rb']
  end
end

# 与えられたリソースに対応する統合テストを返す
def integration_tests(resource = :all)
  if resource == :all
    Dir["test/integration/*"]
  else
    Dir["test/integration/#{resource}_*.rb"]
  end
end

# インターフェースが該当するすべてのテストを返す
def interface_tests
  integration_tests << "test/controllers/"
end

# 与えられたリソースに対応するコントローラのテストを返す
def controller_test(resource)
  "test/controllers/#{resource}_controller_test.rb"
end

# 与えられたリソースに対応するすべてのテストを返す
def resource_tests(resource)
  integration_tests(resource) << controller_test(resource)
end
```

クラウドIDEではもうひとつ手順が必要。次のややこしいコマンドを実行してプロジェクト内の全ファイルをGuardで監視できるようにする。

```
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p
```

Guardの設定が完了したら、新しいターミナルで次のコマンド実行する。
`$ bundle exec guard`

```
ubuntu:~/environment/sample_app (master) $ bundle exec guard
12:39:16 - INFO - Guard::Minitest 2.4.6 is running, with Minitest::Unit 5.11.3!
12:39:18 - INFO - Guard is now watching at '/home/ubuntu/environment/sample_app'
[1] guard(main)> 
```

テストを変更ファイルだけでなく、フルで実行したい場合は、guard>プロンプトでReturnキーをおします。Guardを終了するにはCtrl+Dキーを押す。
はっきりしたした原因がないのにテストが失敗する場合は次のようにGuardをいったん終了し、Springを止めて再起動してみましょう。

```
$ bin/spring stop    # テストが原因不明で動かなくなったら、このコマンドを実行してみる
$ bundle exec guard
```

ここまでで行動なセットアップは終了です。変更を忘れずにコミットしておく

```
$ git add -A
$ git commit -m "Complete advanced testing setup"
```