【自分用】railsチュートリアル 5章

レイアウトを作成する
Bootstrapフレームワークを組み込み、カスタムスタイルを追加する
作成したページへのリンクをレイアウトに追加する
パーシャル、Railsのルーティング、Asset Pipeline、Sassについても見ていく

5.1 構造を追加する
レイアウトにいくつかの構造とCSSを与えて、スタイルを追加する
Bootstrap、パーシャル機能を使ってレイアウトのコードを整えていく
モックアップ（ワイヤーフレームともいう）実装後のアプリケーションの外観をスケッチしたものを使っていく
この章ではサイトロゴ、ナビゲーションヘッダー、サイトフッターを含む静的ページを開発する
新しいブランチを作成しておく
$ git switch -c filling-in-layout

5.1.1 ナビゲーション
サイトのレイアウトファイルapplication.html.erbにHTML構造を追加し、更新する
この更新には、領域(divタグ)の追加、CSSクラスの追加、サイトナビゲーションの起点となる領域の追加も含まれる

リスト5.1 構造を追加したレイアアウト
railsではデフォルトでHTML5を使う(<!DOCTYPE html>)
headタグに続くセクションには、サイトのロゴを表示するheader、divタグによるいくつかの領域、ナビゲーションリンクのリストがある
headerタグは、ページ上部に来るべき要素を表す。このheaderタグには、navbar、navbar-fixed-top、navbar-inverseという３つのCSSクラスがスペース区切りで与えられている
全てのHTML要素にはクラスとidの両方を指定できる
クラスやidは単なるラベルでCSSでスタイルを指定するのに便利
クラスとidの違いはクラスはページ内で何度も使えるのに対し、idはページ内で一度しか使えない
今回の場合、すべてのnavbarクラスには、bootstrapによって特別な意味が与えられている

headerタグの内側にdivタグがある
divタグは一般的な表示領域を表し、要素を別々のパーツに分けるときに使われる
古いスタイルのHTMLではdivタグはサイト内のほぼ全ての領域で使われていた。HTML5からはよく使われる領域ごとに細分化できるようになり、具体的にはheader要素、nav要素、section要素が新たに使えるようになった
headerタグのクラスと同様にdivタブにもCSSクラス（container）が与えられているが、これはBootstrapにおいて意味を持つ

divに続いてERBコードが出現する
リンクを生成するためにrailsヘルパーのlink_toを使う。これはaタグを生成する
link_toの1引数はリンクテキスト、2引数はURL。このURLはあとで名前付きルーティングに置き換える。今はダミーとして'#'を置いておく
３引数はオプションハッシュで、cssidのlogoを指定している
railsヘルパーはオプションのハッシュを引数として受け取ることがよくあ離、これによりrailsのコードから離れることなく任意のHTMLオプションを柔軟に追加できる

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

レイアウトの最後の部分はメインコンテンツ用のdiv
containerクラスもbootstrapにおいて特別な意味を持つ
yieldメソッドはWebサイトのレイアウトにページごとの内容を挿入

リスト5.2 home.html.erbビューに特別な要素をいくつか追加
divタグのCSSクラスjumbotronやsignupボタンのbtnクラス、btn-lgクラス、btn-primaryクラスは全てbootstrapにおいて意味を持つ
2番目のlink_toでは、引数として画像ファイルのパスと任意のオプションハッシュを受け取るimage_tagヘルパーの機能が示されている
このヘルパーではシンボルを使ってalt属性やwidth属性などを設定できる
リスト5.3 画像をダウンロード

リスト5.2でimage_tagヘルパーを使っているのでrailsは該当する画像ファイルをアセットパイプラインを通してapp/assets/images/ディレクトリの中から探してくる

image_tagの効果を確かめるためにブラウザから生成されたHTMLを見てみる
img alt="Rails logo" width="200px" src="/assets/rails-<long string>.svg"
<long string>の部分は、ファイルが一意になるようrailsによって追加される
これは画像ファイルを新しい画像に更新したときにブラウザ内に保存されたキャッシュに意図的にヒットさせないようにするための仕組み
src属性にはimagesというディレクトリ名が含まれていない
これはassetsディレクトリ内の他のディレクトリ(imagesやjavascripts、stylesheetsなど)も同様
これは高速化のための仕組みで、railsディレクトリ直下の画像をapp/assets/imagesディレクトリにある画像と紐付けている
これによりブラウザから見ると全てのファイルが同じディレクトリにあるように見える

alt属性は画像がない場合に代わりに表示される文字列

5.1.2 BootstrapとカスタムCSS
BootstrapはHTML5アプリケーションに優れたWebデザインとユーザーインターフェース要素を簡単に追加できるCSSフレームワーク
これを使うとアプリをレスポンシブデザイン（どの端末で閲覧してもある程度見栄えが良くなる）にできる

リスト5.5 GemfileにSassのgem追加
bootstrap-sass gemを使って追加する。Bootstrapフレームワークでは動的なスタイルシートを生成するためにLESS CSS言語を使っているrailsのアセットパイプラインはデフォルトでSass言語をサポートする。そのためbootstrap-sassはLESSをSassへ変換し必要なBootstrapファイルを現在のアプリで全て利用できるようにする
rails7からはAsset PipelineのSass機能がsassc-railsという別のgemに切り出された

インストールする
$ bundle install

全てのCSSを一つにまとめる
まずはカスタムCSSファイルを作成する
$  touch app/assets/stylesheets/custom.scss

app/assets/stylesheets/
このディレクトリはAsset Pipelineの一部で、このディレクトリに置かれたスタイルシートはapplication.cssの一部としてWebサイトのレイアウトに読み込まれる
ファイル名のcustom.scssには.scssという拡張子が含まれている。Sass(Sassy CSS)はCSSを拡張した言語で、アセットパイプラインはこのファイルの拡張子を見てSassを処理できるようになる

リスト5.6 カスタムCSSに@importを使ってBootstrapとそれに関連するSprockets(app/assets配下にあるjsファイルとcssファイルをそれぞれ1つにまとめる)を読み込む

リスト5.7
webサイト全体にわたってレイアウトと個別のページにスタイルを与える

リスト5.8 CSSを追加する
リスト5.9 ヘッダーのCSS

5.1.3 パーシャル（partial）
リスト5.12 レイアウトにヘッダーのパーシャル追加
renderというrailsヘルパー呼び出しを使ってヘッダー情報を置き換えている
app/views/layouts/_header.html.erbというファイルを探してビューに挿入
ファイル名の先頭の_は、パーシャルであることを示す

パーシャルを動作させるために対応するファイルとコンテンツを作る
リスト5.13 headerのパーシャル
リスト5.14 footerのパーシャル
リスト5.15 レイアウトにfooterパーシャル追加
リスト5.16 footer用css

5.2 Sassとアセットパイプライン
cssや画像などの静的コンテンツの作成と管理を強化するアセットパイプラインとcss生成ツールのSassについて見ていく

5.2.1 アセットパイプライン
アセットディレクトリ、マニフェストファイル、プリプロセッサエンジンの3つの機能を見ていく

アセットディレクトリ
静的ファイルを目的別に分類する、３つのディレクトリ
app/assets 現在のアプリケーション固有のアセット
lib/assets あなたの開発チームによって作成されたライブラリ用のアセット
vendor/assets サードパーティのアセット（デフォルトでは存在しない）

これらのディレクトリには２つのアセットクラス用のサブディレクトリがある
例
$ ls app/assets/
config  images  stylesheets
画像用とCSS用のサブディレクトリがある

custom.scssはサンプルアプリケーション固有のアセットなので、app/assets/stylesheetsに配置するのが適切

マニフェストファイル
静的ファイル（アセット）を上記の場所へそれぞれ配置すれば、マニフェストファイルを使って、それらをどのように１つのファイルにまとめるのかrailsに指示できる
実際にアセットをまとめる処理を行うのはSprocketsというgem
マニフェストファイルはCSSとJavaScriptには適用されるが、画像ファイルには適用されない

リスト5.18 アプリケーション固有のCSS用マニフェストファイル
*= require_tree .　app/assets/stylesheetsディレクトリ中のすべてのCSSファイルをアプリCSSに含めるよう指示
*= require_self  CSSの読み込みシーケンスの中でapplication.css自身もその対象に含めるよう指示

railsのデフォルトのマニフェストファイルに変更を加える必要がないが、もし必要ならrailsガイドのアセットパイプラインを参照

プリプロセッサエンジン
railsは必要なアセットをディレクトリに配置してまとめた後、さまざまなプリプロセッサエンジンを実行して結合することでブラウザに配信できるようにする
railsではどのファイルに対してどのプリプロセッサを使うかファイル名の拡張子で判断する
.erbであればERB用のプリプロセス(前処理)を実行し.scssであればSass用のプリプロセスを実行する

本番環境での効率性
アセットパイプラインの最大のメリットの一つは本番のアプリで効率的になるように最適化されたアセットを自動的に生成できること
従来はCSSを整理するのに機能ごとにファイルを分割しインデントを多用して読みやすくしていたが、これは本番環境にとっては非効率。理由は最小化されていないCSSファイルを多数のCSSファイルに分割するとページの読み込み時間が遅くなるから

アセットパイプラインを使うと開発効率も読み込み時間も良し
開発環境では読みやすいフォーマットで整理しておき、本番環境ではアセットパイプラインでファイルを最小化すればよい
具体的にはアセットパイプラインが全てのスタイルシートを結合して１つのCSSファイルapplication.cssにまとめる。さらにそれらのファイル全てに対して不要な空白やインデントを取り除く処理を行い、ファイルサイズを最小化する。
Renderの場合、ダッシュボードからアプリのWEB SERVICEを開きSettingsタブを開いてBuild Commandを確認

5.2.2 素晴らしい構文を備えたスタイルシート
Sassはスタイルシートを記述するための言語
ネストと変数について見ていく（ミックスインについては7で）

SassはSCSSフォーマットに対応している。SCSSはCSSに新しい機能を追加しただけだからCSSファイルはすべてSCSSファイルとしても扱える。既存の記法ルールを使っているプロジェクトにとっても互換性がある

ネスト
スタイルシート内に共通のパターンがある場合は要素をネストさせることができる
.center {
  text-align: center;
}

.center h1 {
  margin-bottom: 10px;
}
↓↓↓
.center {
  text-align: center;
  h1 {
    margin-bottom: 10px;
  }
}
ネストの内側のh1は.centerのルールを継承している

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
}

#logo:hover {
  color: #fff;
  text-decoration: none;
}

この場合２つ目のルールをネストするには#logoを参照する必要がある
SCSSは&を使う

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
  &:hover {
    color: #fff;
    text-decoration: none;
  }
}

SassはSCSSをCSSに変換する際に&:hoverを#logo:hoverに置き換える

ネスト機能はフッターのCSSでも使える
リスト5.16のコードはSCSSを使って書き換えられる

変数
Sassでは変数が定義できる
 $light-gray: #777;
h2 {
  .
  .
  .
  color: $light-gray;
}

変数名は生の値よりも意味が分かりやすいので変数が繰り返し使われないとしても、変数名を与えることは有用
Bootstrapでは多くの色に変数が定義されていて、LESS変数一覧で参照できる
SassでなくLESSを使って変数が定義されているがbootstrap-sassというgemを使えば良い
LESSでは@を使うのに対しSassでは$を使う

リスト5.19 ネストや変数を使ってSCSSファイルを書き直す

5.3 レイアウトのリンク
'#'で代用されていたリンクを書き換える
リンクを直接記述することもできるが名前付きルーティングを使うのが慣例
<a href="/static_pages/about">About</a>
<%= link_to "About", about_path %>

コードの意味が分かりやすくなりabout_pathの定義を変えればabout_pathが使われている全てのURLを変更できるため。柔軟性が高まる

表5.1  ページ名とURLと名前付きルーティング

5.3.1 Contactページ
リスト5.20 Contactページのテスト
リスト5.22 Contactページのルート追加
リスト5.23 Contactページ用のアクション追加
リスト5.24 Contactページのビュー追加

5.3.2 RailsのルートURL
名前付きルーティングをサンプルアプリケーションの静的ぺーじで使うためにルーティング用ファイル(config/routes.rb)を編集していく

ルートURLを定義するコードを３つ見てきた
root "application#hello"
root "users#index"
root "static_pages#home"
いずれもrootメソッドでルートURL"/"をコントローラのアクションに紐づけている
ルーティングを定義することの効果はブラウザからアクセスしやすくするだけでなく、それ以外に生のURLでなく名前付きルーティングを使ってURLを参照できる
ルートURLを定義すると、root_pathやroot_urlといったメソッドを通してURLを参照できる
root_path -> '/'　　ルートURL以下の文字列を返す
root_url  -> 'https://www.example.com/'　　完全なURLの文字列を返す

基本的には_pathを使い、リダイレクトの場合のみ_urlを使う

名前付きルーティングをgetルールを使って定義する
get "static_pages/help"
↓
get  "/help", to: "static_pages#help"
getリクエストが/helpに送信された時にStaticPagesコントローラのhelpアクションを呼び出す
ルートURLの時と同様help_pathやhelp_urlといった名前付きルーティングも使える

リスト5.２６　静的なページのルーティング一覧
リスト5.２７　テスト更新

5.3.３ 名前付きルーティング
レイアウトの中で名前付きルーティングが使えるようになったので書き換えていく
リスト5.29 headerパーシャル
リスト5.３０　　footerパーシャル

5.3.４ リンクのテスト
レイアウト内のリンクが正しく動いているかチェックするテストを書く
統合テストを使って作業を自動化する

site_layoutというテストのテンプレート作成
$ rails generate integration_test site_layout
今回のテストの目的はアプリのHTML構造を調べてレイアウトの各リンクが正しく動くかどうか確認すること
1 ルートURL（Homeページ）にGetリクエスト
2 正しいページテンプレートが描画されているか確認
3 Home Help About Contactの各ページへのリンクが正しく動くか確認

リスト5.31 assert_templateメソッドを使ってHomeページが正しいビューをレンダリングしているか確認
assert_select "a[href=?]", about_path
?をabout_pathに置き換えている
ルートURLへのリンクは２つある（ロゴ、ナビゲーションバー）のでcount:2

表5.2 assert_selectの使用例

5.4 ユーザー登録: 最初のステップ
ユーザー登録ページへのルーティングを作成
そのために2番目のコントローラ作成

5.4.1 Usersコントローラ
2番目のコントローラであるUsersコントローラを作成する
generateを実行して新規ユーザー登録ページを持つコントローラ
新規ユーザー用のアクションをnewとする generate controllerの引数にnewを渡す
リスト5.37 Usersコントローラの生成(newアクション追加)
リスト5.38 newアクションUsersコントローラ
リスト5.39 ビュー
リスト5.40 Userページの最初のテスト

5.4.2 ユーザー登録用URL
新規ユーザー用のページが/users/newになったが、/signupにしたい
ユーザー登録URL用にget "/signup"のルーティング追加
リスト5.42 ユーザー登録ページのルーティング

テスト修正
リスト5.43 Usersコントローラのテストで名前付きルーティングを使う
リスト5.44 名前付きルーティングを使ってHomeページにリンク追加
リスト5.45 ユーザー登録ビュー

5.5 最後に
この章ではレイアウトを形にした
以後、ユーザー登録、ログイン、ログアウトできるユーザーを追加する
マイクロポストも追加する
最後は他のユーザーをフォローできるようにする

5.5.1 本章のまとめ
HTML5を使ってheaderやfooter、logoやbodyといったコンテンツのレイアウトを定義した
railsのパーシャルは効率化のために使われ別ファイルにマークアップを切り出せる
cssはcssクラスとidを使ってレイアウトやデザインを調整する
bootstrapフレームワークを使うといい感じのデザインを素早く実装できる
sassとアセットパイプラインは開発効率のために切り分けられたcssの冗長な部分を圧縮し本番環境に最適化した結果を出力する
railsのルーティングでは自由にルールを定義することができ、またその際に名前付きルーティングも使えるようになる
統合テストはブラウザによるページ間の遷移を効率的にシュミレートする