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

###第5章
###レイアウトを作成する

###演習

1. Webページと言ったらネコ画像、というぐらいにはWebにはネコ画像が溢れていますよね。リスト 5.4のコマンドを使って、図 5.3のネコ画像をダウンロードしてきましょう11 。

解：以下コマンドを入力実行するだけ。

```
 curl -OL https://cdn.learnenough.com/kitten.jpg
```

2. `mv`コマンドを使って、ダウンロードした`kitten.jpg`ファイルを適切なアセットディレクトリに移動してください（参考: 5.2.1）。

解：

```
ubuntu:~/environment/sample_app (filling-in-layout) $ mv kitten.jpg app/assets/images/
```

3. `image_tag`を使って、kitten.jpg画像を表示してみてください。(図 5.4)。

解：下記コードを/sample_app/app/views/static_pages/home.html.erb内に追加した。

```
<%= link_to image_tag("kitten.jpg", alt: "kitten jpg", width: "200px"),
                      "#" %>
```

###5.1.2　BootstrapとカスタムCSS

Bootstrapを追加しましょう。これは`bootstrap-sass`gemを使ってRailsアプリケーションに導入できます。

######リスト 5.5:Gemfileにbootstrap-sassを追加する


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

gem 'rails',          '6.0.3'
gem 'bootstrap-sass', '3.4.1'
gem 'puma',           '4.3.6'
.
.
.
```
Gemfileの中の該当の行を追加し、保存し、bundle installする

結果

```
ubuntu:~/environment/sample_app (filling-in-layout) $ bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using rake 12.3.3
Using concurrent-ruby 1.1.9
Using i18n 1.8.10
Using minitest 5.11.3
Using thread_safe 0.3.6
Using tzinfo 1.2.9
Using zeitwerk 2.4.2
Using activesupport 6.0.3
Using builder 3.2.4
Using erubi 1.10.0
Using mini_portile2 2.6.1
Using racc 1.5.2
Using nokogiri 1.12.4 (x86_64-linux)
Using rails-dom-testing 2.0.3
Using crass 1.0.6
Using loofah 2.12.0
Using rails-html-sanitizer 1.4.2
Using actionview 6.0.3
Using rack 2.2.3
Using rack-test 1.1.0
Using actionpack 6.0.3
Using nio4r 2.5.8
Using websocket-extensions 0.1.5
Using websocket-driver 0.7.5
Using actioncable 6.0.3
Using globalid 0.5.2
Using activejob 6.0.3
Using activemodel 6.0.3
Using activerecord 6.0.3
Using mimemagic 0.3.10
Using marcel 0.3.3
Using activestorage 6.0.3
Using mini_mime 1.1.1
Using mail 2.7.1
Using actionmailbox 6.0.3
Using actionmailer 6.0.3
Using actiontext 6.0.3
Using public_suffix 4.0.6
Using addressable 2.8.0
Using ansi 1.5.0
Fetching execjs 2.8.1
Installing execjs 2.8.1
Fetching autoprefixer-rails 10.3.3.0
Installing autoprefixer-rails 10.3.3.0
Using bindex 0.8.1
Using msgpack 1.4.2
Using bootsnap 1.4.5
Using ffi 1.15.3
Using sassc 2.4.0
Fetching bootstrap-sass 3.4.1
Installing bootstrap-sass 3.4.1
Using bundler 1.17.2
Using byebug 11.0.1
Using regexp_parser 1.8.2
Using xpath 3.2.0
Using capybara 3.28.0
Using childprocess 2.0.0
Using coderay 1.1.3
Using formatador 0.3.0
Using rb-fsevent 0.11.0
Using rb-inotify 0.10.1
Using ruby_dep 1.5.0
Using listen 3.1.5
Using lumberjack 1.2.8
Using nenv 0.3.0
Using shellany 0.0.1
Using notiffany 0.1.3
Using method_source 1.0.0
Using pry 0.14.1
Using thor 1.1.0
Using guard 2.16.2
Using guard-compat 1.2.1
Using guard-minitest 2.4.6
Using jbuilder 2.9.1
Using ruby-progressbar 1.11.0
Using minitest-reporters 1.3.8
Using puma 4.3.6
Using rack-proxy 0.7.0
Using railties 6.0.3
Using sprockets 3.7.2
Using sprockets-rails 3.2.2
Using rails 6.0.3
Using rails-controller-testing 1.0.4
Using rubyzip 1.3.0
Using sass-listen 4.0.0
Using sass 3.7.4
Using tilt 2.0.10
Using sass-rails 5.1.0
Using selenium-webdriver 3.142.4
Using spring 2.1.0
Using spring-watcher-listen 2.0.1
Using sqlite3 1.4.1
Using turbolinks-source 5.2.0
Using turbolinks 5.2.0
Using web-console 4.0.1
Using webdrivers 4.1.2
Using webpacker 4.0.7
Bundle complete! 24 Gemfile dependencies, 94 gems now installed.
Gems in the group production were not installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```

次にカスタムCSSを動かすために、カスタムCSSファイルを作る

```
ubuntu:~/environment/sample_app (filling-in-layout) $ touch app/assets/stylesheets/custom.scss
```

カスタムCSS用のファイルを作成したら、リスト5.6のように`@import`を使って、Bootstrap(とそれに関連するSprokets)を読み込みます。

######リスト 5.6:Bootstrap CSSを追加する

```ruby:app/assets/stylesheets/custom.scss
@import "bootstrap-sprockets";
@import "bootstrap";
```

「rails serverを再起動してブラウザで確認すると下記のようになった。」

![新しいビットマップ イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933665/4c93bdfa-f28e-8373-6134-a14a29b1cfa6.jpeg)


次にWebサイト全体にわたってレイアウトと個別のページにスタイルを与えるためのCSSを追加します。テストの結果を図5.6に示します。

###リスト 5.7:すべてのページに適用される共通のスタイルをCSSに追加する

```ruby:app/assets/stylesheets/custom.scss
@import "bootstrap-sprockets";
@import "bootstrap";

/* universal */

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

.center {
  text-align: center;
}

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

###リスト 5.8:洗練されたタイポグラフィーを利用するためのCSSを追加する

```ruby:app/assets/stylesheets/custom.scss
/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: #777;
}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}
```


###リスト　5.9:サイトロゴにCSSを追加する

```ruby:app/assets/stylesheets/custom.scss
/* header */

#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;
}
```

### 演習
1. リスト 5.10を参考にして、5.1.1.1で使ったネコ画像をコメントアウトしてみてください。また、ブラウザのHTMLインスペクタ機能を使って、コメントアウトするとHTMLのソースからも消えていることを確認してみてください。

#######リスト　5.10:埋め込みRubyのコードをコメントアウトする

```
<%#= image_tag("kitten.jpg", alt: "Kitten") %>
```

解：
「<%の後に#を挿入するようだね。我が環境では下記のようにした」


```
<%#= link_to image_tag("kitten.jpg", alt: "kitten jpg", width: "200px"),
                      "#" %>
```


2. リスト5.11のコードを`custom.scss`に追加し、すべての画像を非表示にしてみてください。うまくいけば、Railsのロゴ画像がHomeページから消えるはずです。先ほどと同様にインスペクタ機能を使って、今度はHTMLのソースコードは残ったままで、画像だけが表示されなくなっていることを確認してみてください。

#######リスト 5.11:すべての画像を非表示にするCSS

```
img {
  display: none;
}
```



解：![新しいビットマップ イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933665/db61514b-d753-8a09-fcde-a3bd982dec54.jpeg)


「画像だけ消えたが、ソースにはある」

###5.1.3 パーシャル(partial)

HTML `shim`だけで3行も占有している、これを隠す。HTMLヘッダーでは論理的な単位として分けられるので一箇所にまとめられると便利。Railsでは**パーシャル(partial)**という機能でこのような課題を解決できる。

######リスト 5.12:レイアウトにshimとheaderのパーシャルを追加する。

```ruby:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></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' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>
```

次のように`render`というRailsヘルパーを呼び出しだけを使って、HTMLshimのスタイルシートを置換している。

```
<%= render 'layouts/shim' %>
```

この行では、`app/views/layouts/_shim.html.erb`というファイルを探して内容を評価し、結果をビューに挿入している。

パーシャルで使う普遍的な命名規約はファイル名`_shim.html.erb`の先頭にあるアンダースコア。

######リスト 5.13:HTML shim用パーシャル

```ruby:app/views/layouts/_shim.html.erb
<!--[if lt IE 9]>
  <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
  </script>
<![endif]-->
```

同様にヘッダー情報

######リスト 5.14: header用のパーシャル

```ruby: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>
```

続いてフッター。

######リスト 5.15:サイトのfooter用のパーシャル

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

footerパーシャルは、スタイルシートやheaderパーシャルのときと同じ方法でレイアウト中に追加できます。(リスト 5.16)。

######リスト 5.16:レイアウトにfooterパーシャルを追加する。

```ruby:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></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' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
      <%= render 'layouts/footer' %>
    </div>
  </body>
</html>
```

次はfooterにもスタイルを足します。

######リスト 5.17:サイトにfooter用CSSを追加する

```ruby:app/assets/stylesheets/custom.scss
.
.
.
/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid #eaeaea;
  color: #777;
}

footer a {
  color: #555;
}

footer a:hover {
  color: #222;
}

footer small {
  float: left;
}

footer ul {
  float: right;
  list-style: none;
}

footer ul li {
  float: left;
  margin-left: 15px;
}
```

「rails serverを立ち上げてプレビューで確認すると下記のとおり。」

![新しいビットマップ イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933665/e4d0a3b7-b4cc-34f5-de7c-ff8431e0d913.jpeg)


###演習

1. Railsがデフォルトで生成する`head`タグの部分を、リスト 5.18のように`render`に置き換えてみてください。ヒント: 単純に削除してしまうと後でパーシャルを１から書き直す必要が出てくるので、削除する前にどこかに退避しておきましょう。

解：既存のapplication.html.erbをコピーして、名前を編集して保存し、演習用のapplication.html.erbファイルをリスト5.18をコピペしする。

2. リスト 5.18のようなパーシャルはまだ作っていないので、現時点ではテストは<font color="red">**red**</font>になっているはずです。実際にテストを実行して確認してみましょう。

解：エラーでる。

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test
Running via Spring preloader in process 5568
Started with run options --seed 21006

ERROR["test_should_get_about", #<Minitest::Reporters::Suite:0x0000558c74f03268 @name="StaticPagesControllerTest">, 0.20977071799984515]
 test_should_get_about#StaticPagesControllerTest (0.21s)
ActionView::Template::Error:         ActionView::Template::Error: Missing partial layouts/_rails_default with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
          * "/home/ubuntu/environment/sample_app/app/views"
          * "/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actiontext-6.0.3/app/views"
          * "/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actionmailbox-6.0.3/app/views"
        
            app/views/layouts/application.html.erb:5
            test/controllers/static_pages_controller_test.rb:17:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_help", #<Minitest::Reporters::Suite:0x0000558c750c3c60 @name="StaticPagesControllerTest">, 0.2389002539998728]
 test_should_get_help#StaticPagesControllerTest (0.24s)
ActionView::Template::Error:         ActionView::Template::Error: Missing partial layouts/_rails_default with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
          * "/home/ubuntu/environment/sample_app/app/views"
          * "/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actiontext-6.0.3/app/views"
          * "/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actionmailbox-6.0.3/app/views"
        
            app/views/layouts/application.html.erb:5
            test/controllers/static_pages_controller_test.rb:11:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_home", #<Minitest::Reporters::Suite:0x0000558c77de6030 @name="StaticPagesControllerTest">, 7.694635728999856]
 test_should_get_home#StaticPagesControllerTest (7.70s)
ActionView::Template::Error:         ActionView::Template::Error: Missing partial layouts/_rails_default with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
          * "/home/ubuntu/environment/sample_app/app/views"
          * "/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actiontext-6.0.3/app/views"
          * "/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actionmailbox-6.0.3/app/views"
        
            app/views/layouts/application.html.erb:5
            test/controllers/static_pages_controller_test.rb:5:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_contact", #<Minitest::Reporters::Suite:0x0000558c77e47768 @name="StaticPagesControllerTest">, 7.740333088999932]
 test_should_get_contact#StaticPagesControllerTest (7.74s)
ActionView::Template::Error:         ActionView::Template::Error: Missing partial layouts/_rails_default with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
          * "/home/ubuntu/environment/sample_app/app/views"
          * "/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actiontext-6.0.3/app/views"
          * "/home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actionmailbox-6.0.3/app/views"
        
            app/views/layouts/application.html.erb:5
            test/controllers/static_pages_controller_test.rb:23:in `block in <class:StaticPagesControllerTest>'

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

Finished in 7.74824s
4 tests, 0 assertions, 0 failures, 4 errors, 0 skips

```

**3.** `layouts`ディレクトリに`head`タグ用のパーシャルを作成し、先ほど退避しておいたコードを書き込み、最後にテストが <font color="green">green</font> に戻ることを確認しましょう。

解：問題にあるようにlayoutsディレクトリに_head.html.erbファイルを作成しその中に、application.html.erbファイルの中の<head>タグ内をコピペする。そののちに再度テストすると<font color:"green">green</font>になる。

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test
Running via Spring preloader in process 8168
Started with run options --seed 43845

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

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

application.html.erbファイルの最終系は下記

```
<!DOCTYPE html>
<html>
    <%= render 'layouts/head' %>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
      <%= render 'layouts/footer' %>
    </div>
  </body>
```

「これだけ見たらシンプル」




###### リスト 5.18: railsのデフォルトのheadタグをrenderに置き換える

```ruby:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= render 'layouts/rails_default' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
      <%= render 'layouts/footer' %>
    </div>
  </body>
</html>
```

## 5.2 Sassとアセットパイプライン

最近のRailsに追加された機能で最も特筆すべき機能の一つは、CSS,JavaScript、画像などの静的コンテンツの生産性と管理を大幅に強化する「**アセットパイプライン(Asset Pipeline)**」です。

### 5.2.1 アセットパイプライン

**アセットディレクトリ**
*  `app/assets`:現在のアプリケーション固有のセット
*  `lib/assets`:あなたの開発チームによって作成されたライブラリ用のアセット
*  `vendor/assets`:サードパーティのアセット(デフォルトでは存在しない)

### マニフェストファイル

### リスト 5.19: アプリケーション固有のCSS用マニフェストファイル

```ruby:app/assets/stylesheets/application.css
/*
 * This is a manifest file that'll be compiled into application.css, which will
 * include all the files listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any
 * plugin's vendor/assets/stylesheets directory can be referenced here using a
 * relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at
 * the bottom of the compiled file so the styles you add here take precedence
 * over styles defined in any other CSS/SCSS files in this directory. Styles in
 * this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self
 */
```

上の行で重要な部分はCSSコメントの中。

```
/*
 .
 .
 .
 *= require_tree .
 *= require_self
*/
```

#######プリプロセッサエンジン

プリプロセッサエンジンは、繋げて実行する(chain)ことができます。

`foobar.js.coffee`
上の拡張子の場合、CooffeeScriptプロセッサ経由で実行される。

アセットパイプラインを使うと「開発効率と読み込み時間のどちらを重視するか」という問題について悩む必要がなくなる。開発環境ではプログラマにとって読みやすいように整理しておき、本番環境ではAsset Pipelineを使ってファイルを最小化すればよい。


### 5.2.2　素晴らしい構文を備えたスタイルシート

**Sass**はスタイルシートを記述するための言語。
**ネスト**
スタイルシート内に共通のパターンがある場合は、要素をネストさせることができる。

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

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

上のルールはSassを使って書き換えることができる。

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

もう少し異なるルールに対してネスト機能を使う例。

```
#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`というidが2回使われている。1回目はロゴ自身を定義するため、2回目は`hover`属性を定義するため。このような場合、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を書き換える。

```
footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid #eaeaea;
  color: #777;
  a {
    color: #555;
    &:hover {
      color: #222;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 15px;
    }
  }
}
```

「SCSSファイルを上記のように編集しながらその都度rails testした。」

###変数

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

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

上のコードの`#777`は薄い灰色を指している。Sassでは、このような値を変数として定義し、次のように変数名を与えることができる。

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

SCSSを次のように書き直す。

```
$light-gray: #777;
.
.
.
h2 {
  .
  .
  .
  color: $light-gray;
}
.
.
.
footer {
  .
  .
  .
  color: $light-gray;
}
```

Bootstrapフレームワークでは多くの色に対して変数名が定義されている。一覧は「[LESS変数一覧](https://getbootstrap.com/customize/#less-variables)」で参照することができる。

その一覧で灰色に対して次の変数名が与えられていることに気が付く。

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

つまり`bootstrap-sass`というgemを使えば、SCSSでも同様に`$gray-light`という変数が使えるので、先ほど定義した`$light-gray`というカスタム変数の代わりに、用意された変数を使ってみる。

```
h2 {
  .
  .
  .
  color: $gray-light;
}
.
.
.
footer {
  .
  .
  .
  color: $gray-light;
}
```

今回取り上げたSassのネスト機能や変数機能を使ってSCSSファイルを全面的に書き直すとリスト5.20になります。

######リスト 5.20:ネストや変数を使って初期のSCSSファイルを書き直した結果

```ruby:app/assets/stylesheets/custom.scss

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

/* mixins, variables, etc. */

$gray-medium-light: #eaeaea;

/* universal */

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

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

/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: $gray-light;
}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}


/* header */

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

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $gray-medium-light;
  color: $gray-light;
  a {
    color: $gray;
    &:hover {
      color: $gray-darker;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 15px;
    }
  }
}
```

###演習
1. 5.2.2で提案したように、footerのCSSを手作業で変換してみましょう。具体的には、リスト 5.17の内容を１つずつ変換していき、リスト 5.20のようにしてみてください。

解：手作業で行ってからrails testをするとエラーが起きたんで、コピペしてしまった。ま、やってみる。

###5.3レイアウトのリンク

**5.3.1 Contactページ**

######リスト 5.21:ContactページのテストRED

```ruby: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", "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

  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "Contact | Ruby on Rails Tutorial Sample App"
  end
end
```

この時点では<font color="red">RED</font>になっているはず。

「なってない？」

######リスト 5.23: Contactページのルートを追加するRED

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

「僕の環境下ではすでに３章の演習でContactページを作ってしまったのでREDにはならないようだ。」

######リスト 5.24:Contactページ用のアクションを追加するRED

```ruby:app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
  .
  .
  .
  def contact
  end
end
```

######リスト　5.25:Contactページのビューを追加するGREEEN

```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>
```

ここで、すべてのテストが<font color="Green">GREEN</font>であることを確認しておいてください。

######リスト 5.26:GREEEN

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test
Running via Spring preloader in process 5211
Started with run options --seed 60587

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

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

###5.3.2 RailsのルートURL

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

ルートURLのようなルーティングを定義することの効果は、ブラウザからアクセスすることだけではなく、生のURLではなく、名前付きルートを使ってURLを参照することができるようになる。

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

######リスト 5.27:静的なページのルーティング一覧RED

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

```ruby
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test
Running via Spring preloader in process 4769
Started with run options --seed 44965

ERROR["test_should_get_help", #<Minitest::Reporters::Suite:0x0000562d0beb69a8 @name="StaticPagesControllerTest">, 0.04282190800006447]
 test_should_get_help#StaticPagesControllerTest (0.04s)
NameError:         NameError: undefined local variable or method `static_pages_help_url' for #<StaticPagesControllerTest:0x00007f1b4065e3b8>
            test/controllers/static_pages_controller_test.rb:11:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_home", #<Minitest::Reporters::Suite:0x00007f1b4038bc58 @name="StaticPagesControllerTest">, 0.1388511140000901]
 test_should_get_home#StaticPagesControllerTest (0.14s)
NameError:         NameError: undefined local variable or method `static_pages_home_url' for #<StaticPagesControllerTest:0x0000562d0a2ddad8>
            test/controllers/static_pages_controller_test.rb:5:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_contact", #<Minitest::Reporters::Suite:0x00007f1b40771e80 @name="StaticPagesControllerTest">, 0.19441799800006265]
 test_should_get_contact#StaticPagesControllerTest (0.19s)
NameError:         NameError: undefined local variable or method `static_pages_contact_url' for #<StaticPagesControllerTest:0x00007f1b4076b030>
            test/controllers/static_pages_controller_test.rb:23:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_about", #<Minitest::Reporters::Suite:0x00007f1b40ac2698 @name="StaticPagesControllerTest">, 0.24751392600001054]
 test_should_get_about#StaticPagesControllerTest (0.25s)
NameError:         NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x0000562d0c607810>
            test/controllers/static_pages_controller_test.rb:17:in `block in <class:StaticPagesControllerTest>'

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

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

######リスト　5.28:StaticPagesで扱う新しい名前付きルートに対するテストGREEN

```ruby:test/controllers/static_pages_controller_test.rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

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

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

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

  test "should get contact" do
    get contact_path
    assert_response :success
    assert_select "title", "Contact | Ruby on Rails Tutorial Sample App"
  end
end
```

```
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

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

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

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

  test "should get contact" do
    get contact_path
    assert_response :success
    assert_select "title", "Contact | Ruby on Rails Tutorial Sample App"
  end
end
```

###演習
1. 実は名前付きルートは、`as:`オプションを使って変更することができます。有名な**Far Side**の漫画に倣って、Helpページの名前付きルートを`helf`に変更してみてください（リスト 5.29）。

######リスト 5.29:　helpをhelfに変更する

```ruby:config/routes.rb
Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help', as: 'helf'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
end
```

2. 先ほどの変更により、テストが<font color="red">RED</font>担っていることを確認してください。リスト5.28を参考にルーティングを更新して、テストを<font color="green">GREEEN</font>にしてみてください。

解：

```ruby:/sample_app/test/controllers/static_pages_controller_test.rb
・
・

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

「にしてから、test実行」

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test
Running via Spring preloader in process 5474
Started with run options --seed 32676

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

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

3. エディタのUndo機能を使って、今回の演習で行った変更をもとに戻してみてください。

解：
windowsを使っているので「Ctrl+z」で戻した。undo機能は上が最新なのか逆なのかわかりにくいので使ってない

###5.3.3　名前付きルート

リスト 5.27でルートを定義したことにより、レイアウトの中で名前付きルートが使えるようになりました。`link_to`メソッドの2番目の引数で適切な名前付きルートを使ってみよう。

最初に、HomeページとHelpページへのリンクを持つheaderパーシャル`_header.html.erb`(リスト 5.30)`から取り掛かる。Web共通の慣習に従って、ロゴにもHomeページへのリンクを追加する。

######リスト 5.30:headerパーシャルにリンクを追加する

```ruby:app/views/layouts/_header.html.erb
<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", root_path, id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home",    root_path %></li>
        <li><%= link_to "Help",    help_path %></li>
        <li><%= link_to "Log in", '#' %></li>
      </ul>
    </nav>
  </div>
</header>
```

footerパーシャル`_footer.html.erb`にもリンクがあります。これらはAboutページとContactページへのリンクです。(リスト 5.31)。

######リスト 5.31:footerパーシャルにリンクを追加する

```ruby:app/views/layouts/_footer.html.erb
<footer class="footer">
  <small>
    The <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
    by <a href="https://www.michaelhartl.com/">Michael Hartl</a>
  </small>
  <nav>
    <ul>
      <li><%= link_to "About",   about_path %></li>
      <li><%= link_to "Contact", contact_path %></li>
      <li><a href="https://news.railstutorial.org/">News</a></li>
    </ul>
  </nav>
</footer>
```

「わが環境でパーシャルのリンクを名前付きルートに変更する際`#`→about_pathにするところ、`about_path`とバッククォートを削除しなかったら、プレビューでルートエラーでた」

###演習

1. リスト 5.29のように`helf`ルーティングを作成し、レイアウトのリンクを更新してみてください。

解：


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

「'static_pages#help'→'static_pages#helf'に変えるだけ」

2. 前回の演習と同様に、エディタのUndo機能を使ってこの演習で行った変更を元に戻してみてください。

解：
「Ctrl＋Zで元に戻しただけ、意味？、最初はas:'helf'で名前変更したけど、今回は直接名前付きルートにした」

###5.3.4　リンクのテスト

リンクのテストが正しく動いているかどうかをチェックするテストを書いてみましょう。ブラウザを立ち上げて<font color="yellow">ルートURL</font>にアクセスし、それぞれのリンクをクリックして確かめてもよいけど、変更するたびにこの作業を繰り返すのは大きな負担。「すでにやったし」

なので、統合テスト(Integration Test)を使い、一連の作業を自動化する。

まずは、`site_layout`というテストのテンプレートを作成するところから始める。

```
ubuntu:~/environment/sample_app (filling-in-layout) $  rails generate integration_test site_layout
Running via Spring preloader in process 24914
      invoke  test_unit
      create    test/integration/site_layout_test.rb
```

######リスト　5.32:レイアウトのリンクに対するテスト GREEN

```ruby:test/integration/site_layout_test.rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  test "layout links" do
    get root_path
    assert_template 'static_pages/home'
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
  end
end
```

リスト　5.32で追加統合テストが通るかどうかは、次のようにRakeタスクを実行することで試すことができる。

######リスト　5.33: GREEN

```
$ rails test:integration
```

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test:integration
Started with run options --seed 19010

 FAIL["test_layout_links", #<Minitest::Reporters::Suite:0x0000555db5515578 @name="SiteLayoutTest">, 2.7456329080014257]
 test_layout_links#SiteLayoutTest (2.75s)
        Expected: 2
          Actual: 1
        test/integration/site_layout_test.rb:8:in `block in <class:SiteLayoutTest>'

02
Finished in 2.75060s
```


「最初エラーが出て、リンク先が一つしか無いって言ってくるので、いろいろ見なおしたら、ヘッダーの中のリンクが名前付きリンクに修正できてないのが原因でした。」
以下修正前

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

修正後

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

「でテストしたら成功。」

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test:integration
Started with run options --seed 54409

  1/1: [=======] 100% Time: 00:00:01, Time: 00:00:01
```

###演習

1. footerパーシャルのabout_pathをcontact_pathに変更してみて、テストが正しくエラーを捕まえてくれるかどうか確認してみてください。

解：

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

「こうして」

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test:integration
Started with run options --seed 31143

 FAIL["test_layout_links", #<Minitest::Reporters::Suite:0x000055770d4ebc48 @name="SiteLayoutTest">, 1.6156713219970698]
 test_layout_links#SiteLayoutTest (1.62s)
        Expected at least 1 element matching "a[href="/about"]", found 0..
        Expected 0 to be >= 1.
        test/integration/site_layout_test.rb:10:in `block in <class:SiteLayoutTest>'

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

Finished in 1.62022s
1 tests, 4 assertions, 1 failures, 0 errors, 0 skips
```

「エラーでた。成功」

2. リスト 5.35で示すように、Applicationヘルパーで使っている`full_title`ヘルパーを、test環境でも使えるようにすると便利です。こうしておくと、リスト 5.36のようなコードを使って、正しいタイトルをテストすることができます。ただし、これは完璧なテストではありません。例えばベースタイトルに「Ruby on Rails Tutoial」といった誤字があったとしても、このテストでは発見することができないでしょう。この問題を解決するためには、`full_title`ヘルパーに対するテストを書く必要があります。そこで、Applicationヘルパーをテストするファイルを作成し、リスト 5.37の**（コードを書き込む）**の部分を適切なコードに置き換えてみてください。ヒント: リスト 5.37では`assert_equal <期待される値>, <実際の値>`といった形で使っていましたが、内部では`==`演算子で期待される値と実際の値を比較し、正しいかどうかのテストをしています。

###リスト　5.35:test環境でもApplicationヘルパーを使えるようにする

```ruby:test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
.
.
.
class ActiveSupport::TestCase
  fixtures :all
  include ApplicationHelper
  .
  .
  .
end
```

#######リスト　5.36:test環境でfull_titleヘルパーを使うGREEN

```test/integration/site_layout_test.rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  test "layout links" do
    get root_path
    assert_template 'static_pages/home'
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
    get contact_path
    assert_select "title", full_title("Contact")
  end
end
```

######リスト　5.37: full_titleヘルパーの単体テスト

```ruby:test/helpers/application_helper_test.rb
require 'test_helper'

class ApplicationHelperTest < ActionView::TestCase
  test "full title helper" do
    assert_equal full_title,         （コードを書き込む）
    assert_equal full_title("Help"), （コードを書き込む）
  end
end
```

「下のようにした」

```ruby:test/helpers/application_helper_test.rb
require 'test_helper'

class ApplicationHelperTest < ActionView::TestCase
  test "full title helper" do
    assert_equal full_title,"Ruby on Rails Tutorial Sample App"
    assert_equal full_title("Help"),"Help|Ruby on Rails Tutorial Sample App"
  end
end
```

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

この説ではレイアウトとルーティングの取り組みにおける頂点として、ユーザー登録ページへのルーティングを作成する。そのために2番目のコントローラを作成することになる。

###5.4.1　Userコントローラ

3.2で、最初のコントローラであるStaticPagesのコントローラを作成した。今度は2番目のコントローラであるUserコントローラを作成する。以前と同様に、`generate`を実行して現時点での要求である新規ユーザー登録ページ(スタブ)を持つ、最も簡単なコントローラを作成する。RESTアーキテクシャの規約に従い、新規ユーザー用のアクションを`new`とする。したがって、`generate controller`の引数に`new`を渡して、自動的にアクションを作成してみましょう。変更結果はリスト5.38。

######リスト　5.38:Userコントローラの作成(newアクションを追加)

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails generate controller Users new
Running via Spring preloader in process 4087
      create  app/controllers/users_controller.rb
       route  get 'users/new'
      invoke  erb
      create    app/views/users
      create    app/views/users/new.html.erb
      invoke  test_unit
      create    test/controllers/users_controller_test.rb
      invoke  helper
      create    app/helpers/users_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/users.scss
```

リスト 5.38により、`new`アクションをもつUserこんとろーら(リスト　5.39)と、スタブのユーザービューを作成します。(リスト 5.40)。この時、新しいUserページ用の小さなリスト(5.41)も作成されていて、この時点ではパスするはずです。



######リスト 5.39:newアクションを持つ最初のUsersコントローラ

```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController

  def new
  end
end
```

#######リスト　5.40:Users用の最初のnewアクション

```ruby:app/views/users/new.html.erb
<h1>Users#new</h1>
<p>Find me in app/views/users/new.html.erb</p>
```

#######リスト　5.41:Userページ用の最初のテスト　GREEN

```ruby:test/controllers/users_controller_test.rb
require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest
  test "should get new" do
    get users_new_url
    assert_response :success
  end

end
```

この時点では、テストは<font color="green">GREEN</font>

#######リスト　5.42:GREEN

「いや、せんかった。」

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test
Running via Spring preloader in process 4240
Started with run options --seed 20308

 FAIL["test_full_title_helper", #<Minitest::Reporters::Suite:0x0000562d19ab30f0 @name="ApplicationHelperTest">, 0.05590767399996821]
 test_full_title_helper#ApplicationHelperTest (0.06s)
        --- expected
        +++ actual
        @@ -1 +1 @@
        -"Help | Ruby on Rails Tutorial Sample App"
        +"Help|Ruby on Rails Tutorial Sample App"
        test/helpers/application_helper_test.rb:6:in `block in <class:ApplicationHelperTest>'

  7/7: [========] 100% Time: 00:00:05, Time: 00:00:05

Finished in 5.71084s
```


「full titleが変だって言ってそう。なので、書いてあるとおりHelp | RubyにしてみたらOKだった」

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails testRunning via Spring preloader in process 4607
Started with run options --seed 60226

  7/7: 
[=========================================================================================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.74736s
7 tests, 17 assertions, 0 failures, 0 errors, 0 skips
```

###演習
1.表 5.1を参考にしながらリスト 5.41を変更し、`users_new_url`ではなく`signup_path`を使えるようにしてみてください。


表 5.1:　サイトリンクのルーティングと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`|


解：

```ruby:/sample_app/test/controllers/users_controller_test.rb
require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest
  test "should get new" do
    get signup_path
    assert_response :success
  end

end
```

「こうした」

2. 先ほどの変更を加えたことにより、テストが red になったことを確認してください。なお、この演習はテスト駆動開発（コラム 3.3）で説明した red / green のリズムを作ることを目的としています。このテストは次の5.4.2で green になるよう修正します。


「redになればOKってこと。」

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test
Running via Spring preloader in process 5683
Started with run options --seed 15610

ERROR["test_should_get_new", #<Minitest::Reporters::Suite:0x0000562d1f2f82d8 @name="UsersControllerTest">, 1.465423111000291]
 test_should_get_new#UsersControllerTest (1.47s)
NameError:         NameError: undefined local variable or method `signup_path' for #<UsersControllerTest:0x0000562d1f2fbd48>
            test/controllers/users_controller_test.rb:5:in `block in <class:UsersControllerTest>'

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

Finished in 1.65077s
7 tests, 16 assertions, 0 failures, 1 errors, 0 skips
```

###5.4.2 ユーザー登録用URL

5.4.1のコードにより新規ユーザー用の動作するページが/users/newにできた。ここで、表5.1を思い出していただきたいのですが、URLは/users/newではなく表のとおりに/signupにしたいと思います。リスト5.27の例に従い、ユーザー登録URL用に`get '/signup'のルートを追加する。

######リスト　5.43:ユーザー登録ページのルートRED

```ruby:config/routes.rb
Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
  get  '/signup',  to: 'users#new'
end
```

リスト 5.44:Usersコントローラのテストで名前付きルートを使うようにするGREEN

「１個前の演習でこれをやった気がするんだけど。」

```ruby:test/controllers/users_controller_test.rb
require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest

  test "should get new" do
    get signup_path
    assert_response :success
  end
end
```

次に、新しく定義された名前付きルートを使って、Homeページボタンに適切なリンクを追加する。ほかのルートと同様、`get '/signup'`と記述したことで、`signup_path`という名前付きルートができ、それをリスト5.45で使います。なお、singupページへのテストは演習にまわすことにします。(5.3.2.1)。

######リスト　5.45:ボタンにユーザー登録ページへのリンクを追加する

```ruby:app/views/static_pages/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!", 'signup_path', class: "btn btn-lg btn-primary" %>
</div>

<%= link_to image_tag("rails.svg", alt: "Rails logo", width: "200px"),
                      "https://rubyonrails.org/" %>

<%#= link_to image_tag("kitten.jpg", alt: "kitten jpg", width: "200px"),
                      "#" %>

```

「上、間違ってる。名前付きルートをシングルクォートで囲ったらリンクが働かないので、シングルクォートを消した。」

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


最後に、signupページ用のカスタムスタブ(stub)のビューを追加します。(5.46)。

######リスト　5.46:最初のユーザー登録ページ(スタブ)

```ruby:app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<p>This will be a signup page for new users.</p>
```

これで、少なくともサインインのルートを追加するまでの間、リンクと名前付きルートが完成しました。(第8章)。結果を図5.11の新規ユーザーのページ(URI/signup)に示します。「URIってURLの間違い？」




###演習

1. もしまだ5.4.1.1の演習に取り掛かっていなければ、まずはリスト 5.41のように変更し、名前付きルート`signup_path`を使えるようにしてください。また、リスト 5.43で名前付きルートが使えるようになったので、現時点でテストが `GREEN` になっていることを確認してください。

解：１個前にやった演習と同じと思うのでパス。

2. 先ほどのテストが正しく動いていることを確認するため、`signup`ルートの部分をコメントアウトし、テスト <font color="red">RED</font> になることを確認してください。確認できたら、コメントアウトを解除して <font color="green">GREEN</font> の状態に戻してください。

解：

```ruby:/sample_app/config/routes.rb
Rails.application.routes.draw do
  get 'users/new'
  root 'static_pages#home'
  get  '/help',    to: 'static_pages#help'
  get  '/about',   to: 'static_pages#about'
  get  '/contact', to: 'static_pages#contact'
  #get '/signup', to: 'users#new'
end
```

「上記のようにコメントアウトした」

```
ubuntu:~/environment/sample_app (filling-in-layout) $ rails test
Running via Spring preloader in process 7100
Started with run options --seed 48184

ERROR["test_should_get_new", #<Minitest::Reporters::Suite:0x0000564799c95068 @name="UsersControllerTest">, 3.882242670999858]
 test_should_get_new#UsersControllerTest (3.88s)
NameError:         NameError: undefined local variable or method `signup_path' for #<UsersControllerTest:0x0000564799c90e00>
            test/controllers/users_controller_test.rb:5:in `block in <class:UsersControllerTest>'

  7/7: [========] 100% Time: 00:00:04, Time: 00:00:04

Finished in 4.15903s
7 tests, 16 assertions, 0 failures, 1 errors, 0 skips
```

「結果、エラーおこしてる、もとに戻して終了。」

3.  リスト 5.32の統合テストにsignupページにアクセスするコードを追加してください（`get`メソッドを使います）。コードを追加したら実際にテストを実行し、結果が正しいことを確認してください。ヒント: リスト 5.36で紹介した`full_title`ヘルパーを使ってみてください。

解：

```ruby:/sample_app/test/integration/site_layout_test.rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  test "layout links" do
    get root_path
    assert_template 'static_pages/home'
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", help_path
    assert_select "a[href=?]", about_path
    assert_select "a[href=?]", contact_path
    get contact_path
    assert_select "title", full_title("Contact")
    get sign_path
    assert_select "title", full_title("new")
  end
end
```

「get sign_pathを追加した」

##5.5 最後に

この章では、アプリケーションのレイアウトを形にし、ルーティングを洗練させました。本書では、以後アプリケーションを肉付けすることに専念します。最初に、ユーザー登録、サインイン、サインアウトできるユーザーを追加します。次にマイクロポストを追加します。最後にユーザーをフォローできるようにします。

Gitを使っている方は、この時点でmasterブランチに変更をマージする。

```
ubuntu:~/environment/sample_app (filling-in-layout) $ git add -A
ubuntu:~/environment/sample_app (filling-in-layout) $ git commit -m "Finish layout and routes"
[filling-in-layout 8a4586f] Finish layout and routes
 23 files changed, 299 insertions(+), 27 deletions(-)
 create mode 100644 app/assets/images/kitten.jpg
 create mode 100644 app/assets/images/rails.svg
 create mode 100644 app/assets/stylesheets/custom.scss
 create mode 100644 app/assets/stylesheets/users.scss
 create mode 100644 app/controllers/users_controller.rb
 create mode 100644 app/helpers/users_helper.rb
 create mode 100644 app/views/layouts/*_application.html.erb
 create mode 100644 app/views/layouts/_footer.html.erb
 create mode 100644 app/views/layouts/_head.html.erb
 create mode 100644 app/views/layouts/_header.html.erb
 create mode 100644 app/views/layouts/_shim.html.erb
 rewrite app/views/static_pages/home.html.erb (99%)
 create mode 100644 app/views/users/new.html.erb
 create mode 100644 test/controllers/users_controller_test.rb
 create mode 100644 test/helpers/application_helper_test.rb
 create mode 100644 test/integration/site_layout_test.rb
 create mode 100644 test_helper.rb
ubuntu:~/environment/sample_app (filling-in-layout) $ git checkout maste
error: pathspec 'maste' did not match any file(s) known to git.
ubuntu:~/environment/sample_app (filling-in-layout) $ git merge filling-in-layout
Already up to date.
ubuntu:~/environment/sample_app (filling-in-layout) $ 
```

続いて、テストスイートを実行して<font color="green">GREEN</font>になるか確認し、問題なければGitHubにプッシュします。

```
ubuntu:~/environment/sample_app (master) $ git push
Username for 'https://github.com/mizumanjyu/sample_app.git': mizumanjyu
Password for 'https://mizumanjyu@github.com/mizumanjyu/sample_app.git': 
Everything up-to-date
```

最後に、Herokuへデプロイします。

「げっ、さっきcheckout masterできてなくって、めちゃくちゃになった、5章最初からだ。」