Ruby on Rails チュートリアル第5章をやってみて

#レイアウトを作成する
■第5章
この章では、アプリケーションにBootstrapフレームワークを組み込み、そして、カスタムスタイルを追加する。
また、これまで作成したページ (HomeやAboutなど) へのリンクをレイアウトに追加する。

##5.1 構造を追加する
レイアウトにいくつかの構造とCSSを与えて、最小限のスタイルを追加する。カスタムCSSルールの他に、Twitter社によるオープンソースのWebデザインフレームワークとして公開しているBootstrapも利用する。

この章では、サイトロゴ、ナビゲーションヘッダー、サイトフッターを含む静的ページを開発する。

###5.1.1 ナビゲーション
第一段階として、サイトのレイアウトファイル`application.html.erb`にHTML構造を追加し、レイアウトファイルを更新する。

サイトのロゴを表示する`header`

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

この`header`タグには、`navbar`、`navbar-fixed-top`、`navbar-inverse`という３つのCSSクラスがスペース区切りで与えられて、すべてのnavbarクラスには、Bootstrapフレームワークによって特別な意味が与えられる。

`header`タグの内側には`div`タグがある。

```
<div class="container">
```

`div`タグは一般的な表示領域を表し、要素を別々のパーツに分けるときに使われる。

HTML5では元々`div`ばかり使われていたが、`header`要素、`nav`要素、`section`要素が新たに使えるようになりました。

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

ダミーURLでは`#`が使われる。

divの内側の2番目の要素は、リストアイテムタグ`li`と順不同リストタグ`ul`によって作られた、ナビゲーションリンクのリスト。
`nav`タグには「その内側がナビゲーションリンクである」という意図を明示的に伝える役割がある。さらに、`ul`タグに付与されている`nav`や`navbar-nav`、`navbar-right`クラスもBootstrapにおいて特別な意味を持つ。


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

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

上と同様、`container`クラスもBootstrapにおいて特別な意味を持つ。`yield`メソッドはWebサイトのレイアウトにページごとの内容を挿入する。

フッター以外のレイアウトは完成。

`home.html.erb`ビューに特別な要素をいくつか追加。

```
<div class="center jumbotron">
  <h1>Welcome to the Sample App</h1>

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

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

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


`div`タグのCSSクラス`jumbotron`や、`signup`ボタンの`btn`クラス、`btn-lg`クラス、`btn-primary`クラスはすべて、Bootstrapにおいて特別な意味を持つ。

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

画像を表示するために、rails.pngというRailsのロゴ画像ファイルを加える。


```
$ curl -o app/assets/images/rails.png -OL railstutorial.jp/rails.png
```

うまくいきました。
![スクリーンショット 2022-02-11 23.13.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2210462/384a5738-5933-a54f-d7ec-1d884ed8e0f1.png)


###5.1.2 BootstrapとカスタムCSS
Bootstrapを使うと、洗練されたWebデザインとユーザーインターフェイス要素を簡単にHTML5アプリケーションに追加することができる。

Gemfileに`bootstrap-sass`を追加する。

```
source 'https://rubygems.org'

gem 'rails',          '5.1.6'
gem 'bootstrap-sass', '3.3.7'
.
```

`bundle install`を実行して、Bootstrapをインストール。

カスタムCSSを作成

```
touch app/assets/stylesheets/custom.scss
```

Bootstrap CSSを追加。

```
@import "bootstrap-sprockets";
@import "bootstrap";
```


Bootstrap CSSのフレームワークを導入。

良い感じに。
![スクリーンショット 2022-02-11 23.52.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2210462/9409ce3c-987f-1cdd-47fc-2a22a4c9e2c6.png)

その後もいろんなCSSを追加。段々洗練されていってきました。


###5.1.3 パーシャル(partial)
パーシャルを使うとスッキリするっぽい。
`application.html.erb`に追加。

```
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',
                               'data-turbolinks-track': 'reload' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>
```

パーシャル動作のために、それに対応するファイルとコンテンツを記述。

HTML shim用のパーシャル
`app/views/layouts/_shim.html.erb`

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

パーシャルでは、自動生成せずに、テキストエディタを使って手動で作成するのが一般的らしい。

header用のパーシャル
`app/views/layouts/_header.html.erb`


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


footer用のパーシャル
`app/views/layouts/_footer.html.erb`

```
<footer class="footer">
  <small>
    The <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
    by <a href="http://www.michaelhartl.com/">Michael Hartl</a>
  </small>
  <nav>
    <ul>
      <li><%= link_to "About",   '#' %></li>
      <li><%= link_to "Contact", '#' %></li>
      <li><a href="http://news.railstutorial.org/">News</a></li>
    </ul>
  </nav>
</footer>
```

その後は他のファイルを色々いじる。

##5.2 Sassとアセットパイプライン
このセクションでは、アセットパイプラインの概要と、素晴らしいCSS生成ツールである「Sass」の使い方について説明する。

###5.2.1 アセットパイプライン
・アセットディレクトリ
・マニフェストファイル
・プリプロセッサエンジン
の3つの主要な機能が理解の対象

####アセットディレクトリ

アセットディレクトリは静的ファイルを目的別に分類する標準的な3つのディレクトリが使われる
`app/assets` 固有
`lib/assets` チーム
`vendor/assets` 第三者

それぞれにサブディレクトリがある。

####マニフェストファイル
静的ファイル(アセット)のまとめ方をRailsに指示することができる。
Sprocketsというgemが実際にアセットをまとめる処理を行う。

マニフェストファイルはCSSとjavascriptには適用されても画像ファイルには適用されない。

`application.css`の中身についての解説。

```
 *= require_tree .
```

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

```
*= require_self
```

CSSの読み込みシーケンスの中で、`application.css`自身もその対象に含めている。


####プリプロセッサエンジン
拡張子を基に処理の判断をしている。
CoffeeScriptはJavaScriptに直してくれる言語。


###5.2.2 素晴らしい構文を備えたスタイルシート
Sassは、スタイルシートを記述するための言語であり、CSSに比べて多くの点が強化されている。
この節では、Sassが提供する2つの重要な機能、ネストと変数について説明する。


SassはSCSSというフォーマットに対応している。SCSSはCSSに新しい機能を追加した、CSS本体を抽象化したフォーマット。

####ネスト
`custom.css`を書き換え。

```
.center {
  text-align: center;
}

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

をSassを使ってこうする。


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

他の箇所も書き換え。

####変数
Sassでは、冗長なコードを削除し、より自由な表現を可能にするために、変数が定義できるようになっている。


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

同じ色を使ってる箇所が。変数として定義し、次のように変数名を与える。

```
$light-gray: #777;
```

色を与えた方がわかりやすい。


##5.3 レイアウトのリンク
レイアウトが仕上がったので、`#`で代用していたリンクを書き換える。

```
<a href="/static_pages/about">About</a>
```

これでもいいが、Rails流ではない。aboutページへのURLは /static_pages/about よりも /about の方がよい。さらに、Railsでは次のようなコードでは名前付きルートを使うのが慣例となっている。

```
<%= link_to "About", about_path %>
```

`about_path`の定義を変えれば`about_path`が使われているすべてのURLを変更できるため、柔軟性が高くなる。

今後使うルーティングたち

| ページ名| URL	 | 名前付きルート|
|:-:|:-:|:-:|
|`Home`|`/`|`root_path`|
| `About`  | `/about	 `  |  `about_path` |
| `Help`  | `/help`  | `help_path`  |
| `Contact`  | `/contact`  | `contact_path`  |
| `Sign up`  | `/signup`  | `signup_path`  |
| `Log in`  | `/login`  | `login_path`  |



###5.3.1 Contactページ
contactは演習で追加済。

###5.3.2 RailsのルートURL
Homeページのルーティングについて見直していく。

`root_path`と`root_url`の違い
前者はルートURL以下の文字列を、後者は完全なURLの文字列を返す。

```
root_path->'/'
root_url -> 'http://www.example.com/'
```

`routes.rb`の回りくどい書き方を変える。

```
get 'static_pages/help'
```

```
get  '/help', to: 'static_pages#help'
```

getルールを使って変更すると、`GET`リクエストが /help に送信されたときにStaticPagesコントローラーの`help`アクションを呼び出してくれるようになる。

他のも同じような感じで書き換え。

###5.3.3 名前付きルート

各URLを作成したので、

```
<%= link_to "About", '#' %>
```

を次のように変更していく

```
<%= link_to "About", about_path %>
```

headerとfooterパーシャルにリンクを追加するとaboutページが表示されました。

![スクリーンショット 2022-02-12 15.54.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2210462/2ad8a5f4-6e24-0a59-84b5-fe7b7faac659.png)


###5.3.4 リンクのテスト

いくつかのリンクを埋めることができたため、これらのリンクが正しく動いているかどうかをチェックするテストを書く。
それぞれのリンクをクリックして確かめることもできるが、毎回そのような作業を繰り返していくのは大きな負担。
統合テスト(Integration Test)を使って一連の作業を自動化する。

コマンドを実行

```
rails generate integration_test site_layout
      invoke  test_unit
      create    test/integration/site_layout_test.rb
```


このとき、Railsは渡されたファイル名の末尾に`test`という文字列を追加する。

今回は、アプリケーションのHTML構造を調べて、レイアウトの各リンクが正しく動くかどうかのチェックが目的。つまり、

1.ルートURL (Homeページ) にGETリクエストを送る。
2.正しいページテンプレートが描画されているかどうか確かめる。
3.Home、Help、About、Contactの各ページへのリンクが正しく動くか確かめる。

```
assert_select "a[href=?]", about_path
```

上のコードでは、Railsは自動的にはてなマーク "?" を`about_path`に置換している。これにより、次のようなHTMLがあるかどうかをチェックすることができる。

```
<a href="/about">...</a>
```

これは、rootのリンクが2つあることを表す。

```
assert_select "a[href=?]", root_path, count: 2
```

`assert_select`は柔軟で、多くのオプションがある。

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

レイアウトとルーティングの取り組みにおける頂点として、ユーザー登録ページへのルーティングを作成する。

###5.4.1 Usersコントローラ
Usersコントローラを作成する。`generate controller`の引数に`new`を渡して、自動的にアクションを作成する

```
$ rails generate controller Users new
```

`app/controllers/users_controller.rb`
`app/views/users/new.html.erb`
`test/controllers/users_controller_test.rb`
ができた。


###5.4.2 ユーザー登録用URL
新規ユーザー用の動作するページが/users/newにできた。URLは/users/newではなく/signupにしたいので色々書き換え。

##感想
HTMLやCSSはほぼ未経験なので、何言ってるかわかんねーみたいなとこは多かったですけど、それでも無事進めれられてよかったです。
Webアプリケーションが自分の手でどんどん出来上がっていくのが楽しいですね。