わたしがRailsチュートリアルで学んだこと【3章】

* 注意：プログラミング歴29日の初心者が書いています

* 注意：間違っていたら優しく教えてください（喜びます）

「Ruby on Rails チュートリアル実例を使ってRailsを学ぼう」
 https://railstutorial.jp/

素晴らしいチュートリアルに感謝します。

#3.2 静的ページ

##トピックブランチを切る

`$ git checkout -b static-pages`:　変更を行う時には、masterではなく、ブランチを作成して作業します。（ブランチを作成することを「切る」と言います）

* 作成したブランチ上で、こまめにコミットしながら作業を進めることができます。でも、本流のmasterにはなんの影響も及ぼしませんので思う存分コミットできます。

* また、複数人がそれぞれブランチを用意して同時進行で作業することも可能です。

#3.2.1 静的なページの生成

##コントローラの生成（ルーティングの追加とviewも同時生成）
`$ generate controller StaticPages home help`：　StaticPagesコントローラを生成する(そのなかには、`home`と`help`というページへのアクションも含む)

同時に「routes.rb」ファイルには、StaticPagesコントローラ内のhomeアクションとhelpアクションで使うルーティングが自動で書き込まれます。

これによって、今後rootURLの末尾に、`/static_pages/home`や`/static_pages/help`と付け加えることで、StaticPagesコントローラ内のhomeアクションとhelpアクションにアクセスが可能です。

```rb
class StaticPagesController < ApplicationController
  def home
  end

  def help
  end
end
```

StaticPagesコントローラ内では、homeアクションとhelpアクションが自動で定義されています。そして、それらによって対応するviewが呼び出されます。

では、viewディレクトリを見てみると、こちらにも自動で`home.html.erb`と`help.html.erb`が生成されています。これがブラウザに表示されるHTMLの一部になっています。


##コントローラの中のクラスとメソッドについて

```rb
class StaticPagesController < ApplicationController
  def home
  end

  def help
  end
end
```
StaticPagesコントローラ内は以下の構成になっています。

* StaticPagesControllerクラスの定義

* クラスメソッド（アクション）の定義: `def~end`部分

Rubyにおいて、メソッドとは関数のことです。
ここでは、「home」「help」という名前のついた関数が定義されていますが、中身は空っぽです。

通常、このように中身の空っぽのメソッドは何もしません。

では、なぜこれらのメソッドは対応するURLリクエストに反応して適切なviewを返してくれるのでしょうか？

それは、StaticPagesControllerクラスがApplicationコントローラクラスを継承しているからです。
そして、ApplocationコントローラクラスはActionController::Baseクラスを継承しています。
ActionController::Baseクラスが、rails特有のコントローラとしての動きを定義しています。

今回あたらしく作成したStaticPagesControllerクラスと、その中の空っぽのメソッドが機能しているのは、ActionController::Baseクラスのコントローラ機能を継承しているからです。




#3.3 テストから始める

テスト駆動開発（TDD）については、以下の動画をみると一通りやるべきこととその動機がわかります。
「50分でわかるテスト駆動開発」
https://channel9.msdn.com/Events/de-code/2017/DO03

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

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


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

##テストから先に書いて、テストが通る実装を書いていく

```rb
assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
```

assert_selectメソッドは、特定のHTMLタグが存在するかどうかをテストします。

```rb
assert_select "title", "タイトル" # titleタグの文字列が、「タイトル」と一致すれば成功。
```

テストに合わせて、それぞれのviewファイルを修正していきます。
１ページ修正するごとにテストを行うと、ちゃんと「failures」が減っていくことがわかります。

##テストコードをリファクタリングする

"Ruby on Rails Tutorial Sample App"　というタイトルの一部がなんども繰り返されています。
同じことをなんども繰り返すのは美しくありませんので、変数に格納してから使う形にリファクタリングします。

以下は`test/controllers/static_pages_controller_test.rb`の一部です。

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

ここではまず、"Ruby on Rails Tutorial Sample App"を`@base_title`というインスタンス変数に格納しています。
「インスタンス変数」とは、同じクラス内で使える変数のことで、頭に＠がついています。
ここでは`StaticPagesControllerTest`クラスで使用可能なインスタンス変数として、`@base_title`を定義しました。

```rb
assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
```

つづいて上記の"Ruby on Rails Tutorial Sample App"を`@base_title`という変数に置き換えていきます。

```rb
assert_select "title", "Home | #{@base_title}"
```

`${@base_title}`という形で、変数が`${}`の中に入っています。
これは、`"文字列"`の中で変数を使う時のルールです。
これを「文字列の式展開」といいます。

もしも変数`@base_title`がもし`${}`の中に入っていなかったら、`"@base_title"`という、ただの文字列として処理されてしまいます。
"Ruby on Rails Tutorial Sample App"として`@base_title`を使う場合は、`${}`の中に入れてあげる必要があるということです。

変更が終わったら、コンソールからテストを走らせて、エラーがないことをチェックします。

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

Rubyの文法をHTML内で使うときには、`<%  %>`でRubyコードを囲みます。

```rb
provide(:title, "Home")
```

ここでは、`:title`というシンボルに、文字列`"Home"`を紐づけて、擬似的なハッシュのようなものを作っています。
ただしprovideメソッドで宣言したこのシンボルと文字列の擬似ハッシュは、このHomeページ内でしか使うことはできません。

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

その後、`yield(:title)`で`文字列"Home"`を呼び出しています。
Rubyの文法をHTML内で使い、かつ結果を出力するときには、`<%=  %>`でRubyコードを囲みます。

今回は呼び出した文字列をHTML内に出力したいので、`<%=  %>`でRubyコードを囲んでいます。


##レイアウトファイルのリファクタリング
レイアウトファイルは、全てのページで共通する<title>や<head>部分を担うviewです。

共通部分をレイアウトファイルに統一することによって、個別のviewファイルの記述を減らし、シンプルに保つことができます。