railsチュートリアル第４章 ヘルパー

一度読んだだけで理解する必要はまったくありません。今後もこの章には頻繁に立ち戻って参照する。

##動機
Rubyに関する知識と経験の限界をを学ぼう。

トピックブランチを作り、そこで変更をコミットする。

```
git checkout -b rails-flavored-ruby
```

###組み込みヘルパー
Railsのレイアウトを使ってビューでの重複を取り除き、ほぼ静的なページを少し更新

```html
<!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
```
Rubyの概念が4つあります。
Railsの組み込み関数、カッコを使わないメソッド呼び出し、シンボル、ハッシュがある。

###カスタムヘルパー
新しく作ったメソッドはカスタムヘルパー
####app/helpers/application_helper.rb

```rb
module ApplicationHelper

  # ページごとの完全なタイトルを返します。
  def full_title(page_title = '')
    base_title = "Ruby on Rails Tutorial Sample App"
    if page_title.empty?
      base_title
    else
      page_title + " | " + base_title
    end
  end
end
```
ウィンドウタイトルを作成するプログラムなのか。
####app/views/layouts/application.html.erb

```html
<!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' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>
```

このヘルパーを定義で、Homeページに余分な「Home」という単語を表示せず、基本タイトルのみ
を正しく表示することもできるようになる。
####test/controllers/static_pages_controller_test.rb

```rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest
  
  def setup
  # メソッド名
    @base_title = "Ruby on Rails Tutorial Sample App"
    # インスタンス変数
  end
  
  test "should get root" do
    get root_url 
    # homeのページに限らず、ホーム画面を表示できるかを聞かれている
    # のでhomeページに絞るにはタイトルを指定しなければならない。
    # route.rbでrootにしたらroot_urlになるらしい。
    assert_response :success
  end
  
  test "should get home" do
    get static_pages_home_url
    # getはGETリクエストで受け付ける普通のWebページを示す
    # GETを受け付けるよね？
    assert_response :success
    # response:successはリクエストが成功し、レスポンスとともに要求に応じた情報が返される
    # GETリクエストが成功、ページが表示されたらいい。
    # response:successは、実際にはHTTPのステータスコード200 OKを指す
    assert_select "title", "Home | #{@base_title}"
    # assert_selectメソッドは、特定のHTMLタグが存在する確認
    # @base_titleに代入する
    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 | #{@base_title}"
  end
  
  test "should get about" do
    get static_pages_about_url
    # aboutページを表示させる（GETリクエスト）
    assert_response :success
    # GETリクエストが成功したかを確認
    assert_select "title", "About | #{@base_title}"
  end
 
  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "Contact | #{@base_title}"
  end
end

```
エラー　

```
ubuntu:~/environment/sample_app (rails-flavored-ruby) $ rails t
Running via Spring preloader in process 7103
Started with run options --seed 31630

ERROR["test_should_get_contact", #<Minitest::Reporters::Suite:0x000056130b228ca0 @name="StaticPagesControllerTest">, 0.09923919900029432]
 test_should_get_contact#StaticPagesControllerTest (0.10s)
ActionView::Template::Error:         ActionView::Template::Error: undefined method `full_title' for #<#<Class:0x00007fbb3ccff838>:0x00007fbb3ccfdb78>
            app/views/layouts/application.html.erb:4
            test/controllers/static_pages_controller_test.rb:46:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_help", #<Minitest::Reporters::Suite:0x00007fbb3cd57e70 @name="StaticPagesControllerTest">, 0.13339053500021691]
 test_should_get_help#StaticPagesControllerTest (0.13s)
ActionView::Template::Error:         ActionView::Template::Error: undefined method `full_title' for #<#<Class:0x00007fbb3ccff838>:0x000056130b2c3bd8>
            app/views/layouts/application.html.erb:4
            test/controllers/static_pages_controller_test.rb:32:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_root", #<Minitest::Reporters::Suite:0x0000561308255690 @name="StaticPagesControllerTest">, 0.19624079599998367]
 test_should_get_root#StaticPagesControllerTest (0.20s)
ActionView::Template::Error:         ActionView::Template::Error: undefined method `full_title' for #<#<Class:0x00007fbb3ccff838>:0x00007fbb3cd8bbf8>
            app/views/layouts/application.html.erb:4
            test/controllers/static_pages_controller_test.rb:12:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_about", #<Minitest::Reporters::Suite:0x0000561309f46ba0 @name="StaticPagesControllerTest">, 0.23440992399991956]
 test_should_get_about#StaticPagesControllerTest (0.24s)
ActionView::Template::Error:         ActionView::Template::Error: undefined method `full_title' for #<#<Class:0x00007fbb3ccff838>:0x00007fbb3c567a08>
            app/views/layouts/application.html.erb:4
            test/controllers/static_pages_controller_test.rb:38:in `block in <class:StaticPagesControllerTest>'

ERROR["test_should_get_home", #<Minitest::Reporters::Suite:0x00007fbb3cb14690 @name="StaticPagesControllerTest">, 0.2679072350001661]
 test_should_get_home#StaticPagesControllerTest (0.27s)
ActionView::Template::Error:         ActionView::Template::Error: undefined method `full_title' for #<#<Class:0x00007fbb3ccff838>:0x000056130a17ee90>
            app/views/layouts/application.html.erb:4
            test/controllers/static_pages_controller_test.rb:19:in `block in <class:StaticPagesControllerTest>'

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

Finished in 0.27328s
5 tests, 0 assertions, 0 failures, 5 errors, 0 skips
```
full_titileが見当たらないらしい。
application_helper.rbで```full_title```ヘルパーを定義していなかった。
定義したら

```
ubuntu:~/environment/sample_app (rails-flavored-ruby) $ rails t
Running via Spring preloader in process 7530
Started with run options --seed 61304

 FAIL["test_should_get_home", #<Minitest::Reporters::Suite:0x000056130d3b56e8 @name="StaticPagesControllerTest">, 1.3727924620006888]
 test_should_get_home#StaticPagesControllerTest (1.37s)
        <Ruby on Rails Tutorial Sample App> expected but was
        <Home | Ruby on Rails Tutorial Sample App>..
        Expected 0 to be >= 1.
        test/controllers/static_pages_controller_test.rb:26:in `block in <class:StaticPagesControllerTest>'

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

Finished in 1.41346s
5 tests, 9 assertions, 1 failures, 0 errors, 0 skips
````
教科書通りになった。
エラーは```<Ruby on Rails Tutorial Sample App>```を期待したが
```<Home | Ruby on Rails Tutorial Sample App>```が表示された。
なのでhomeのhtmlを修正する必要がある。

```html
<!--<% 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>
```
full_titleでウィンドウタイトルが空なので
```<Ruby on Rails Tutorial Sample App>```になるからテストには通りそう。

```
ubuntu:~/environment/sample_app (rails-flavored-ruby) $ rails t
Running via Spring preloader in process 7051
Started with run options --seed 22676

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

Finished in 1.19361s
5 tests, 9 assertions, 0 failures, 0 errors, 0 skips
```
成功。

モジュール、メソッド定義、任意のメソッド引数、コメント、ローカル変数の割り当て、論理値（boolean）、制御フロー、文字列の結合、戻り値の概念を勉強するらしい。

これからはコードのファイルの位置もわかるようにしたい。