Railsチュートリアル 第4章 - 組み込みヘルパーの解説からカスタムヘルパーの実装まで


# [組み込みヘルパー](https://railstutorial.jp/chapters/rails_flavored_ruby?version=5.1#sec-built_in_helpers)

```erb:
<%= stylesheet_link_tag 'application', media: 'all',
                                       'data-turbolinks-track': 'reload' %>
```

Railsチュートリアル本文によれば、大雑把には以下の動作内容となるそうです。

* Railsの組み込み関数`stylesheet_link_tag`を呼び出している
* `application.css`を全てのメディアタイプで使えるようにしている

Railsチュートリアル本文は、以下の概念についてこれから学習するともあります。期待して待ちましょう。

* Railsの組み込み関数
* カッコを使わないメソッド呼び出し
* シンボル
* ハッシュ

# [カスタムヘルパー](https://railstutorial.jp/chapters/rails_flavored_ruby?version=5.1#sec-custom_helpers)

## タイトル行の現在の挙動

現在、`app/views/layouts/application.html.erb`におけるタイトル行の定義は以下のようになっています。

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

例えば、`app/views/static_pages/home.html.erb`に以下のような変更を加えた上で、Webブラウザで開発環境の/homeを表示したらどうなるでしょうか。

```diff:app/views/static_pages/home.html.erb
- <% 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>
```

<img width="205" alt="スクリーンショット 2019-08-16 10.10.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/5a0ab607-c546-8b40-072e-9a713a210df2.png">

先頭に余分な縦棒 | が残ってしまっていますね。この縦棒を消すためにはどうすればよいのでしょうか。

## `full_title`ヘルパーを定義する

以下のようなヘルパーを定義する、というのが一つの方法です。

```ruby:app/helpers/application_helper.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
```

このヘルパーを使うことにより、以下のようにレイアウトをシンプルにすることができます。

```diff:
- <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
+ <title><%= full_title(yield(:title)) %></title>
```

変更前後の`app/views/layouts/application.html.erb`の内容差分は以下のとおりになります。

```diff:app/views/layouts/application.html.erb
 <!DOCTYPE html>
 <html>
   <head>
-    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
+    <title><%= full_title(yield(:title)) %></title>
     <%= csrf_meta_tags %>
 
     <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
```

# Homeページに基本タイトルのみを表示するようにする

まず、テストを以下のように書き換えます。

```diff:test/controllers/static_pages_controller_test.rb

```

`rails test`してみます。

```:bash
# rails test
...略

 FAIL["test_should_get_home", StaticPagesControllerTest, 0.8954415000043809]
 test_should_get_home#StaticPagesControllerTest (0.90s)
        <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:17:in `block in <class:StaticPagesControllerTest>'

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

Finished in 0.97713s
5 tests, 9 assertions, 1 failures, 0 errors, 0 skips
```

一つ失敗したテストがありますね。「Homeビューのtitle要素の内容が、テストケースで定義した内容と異なる」という失敗のようです。ひとまず、`app/views/static_pages/home.html.erb`の先頭行にある`<% provide(:title, "Home") %>`というコードを削除してみます。

```diff:app/views/static_pages/home.html.erb
- <% 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>
```

再度`rails test`します。

```:bash
# rails test
...略

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

Finished in 0.87270s
5 tests, 9 assertions, 0 failures, 0 errors, 0 skips
```

テストが成功するようになりました。