【Rails】ページごとにタイトルの表示を変える設定


はじめに

titleタグのタイトルをページ(view)ごとに、異なる内容を表示する方法です。
以下の画像通り、タイトルに「商品名 - Store」が作成できます。

Qiita初投稿のため、分かりにくい点や間違いがあれば指摘をお願いいたします。

到達点

以下の4点を達成する
productsshowページのタイトルに商品名を表示
 「商品名 - Store」

categoriesshowページタイトルに、カテゴリー名を表示
 「カテゴリー名 - Store」

・他のページは、固定のタイトルをつける
 「Store」

rspecでテストをグリーンにする

流れ

① application.html.erbにタイトルの共通化
② application_helper.rbを作成し、タイトルの内容を記述
③ "shared/_page_title.html.erb"(partial)を作成
④ 各showページに_page_title.html.erbをレンダリング
⑤rspecでhelperのテスト

① application.html.erbにタイトルの共通化

application.html.erbのheadタグ内に

<%= full_title(yield(:title)) %> と記述します。
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
  </head>
  <body>
 # 省略


② application_helper.rbにタイトルの内容を記述

app/helpers/application_helper.rb
module ApplicationHelper
  BASE_TITLE = "Store".freeze
  def full_title(page_title)
    if page_title.blank?
      BASE_TITLE
    else
      "#{page_title} - #{BASE_TITLE}"
    end
  end
end

BASE_TITLEは、定数なので大文字にし、破壊されないようfreezeメソッドを使用します。
関数内の引数であるpage_titleが空の場合とnilの場合の2つを考慮するため、blankメソッドで確認します。
考慮する理由として、関数は様々なケースを想定するため、関数を呼び出した側でエラーを判定するよりも関数内で考慮するほうが一括で行えて楽なため。

③ _page_title.html.erbを作成

各viewで使用するため、sharedフォルダを作成し、_page_title.html.erbを作成します。

app/views/shared/_page_title.html.erb
<% provide(:title, page_title) %>
 <div class="page-title">
  <h2><%= page_title %></h2>
 </div>
# 省略

view内にタイトル文と同じ内容の記述が必要であれば、<%= page_title %> と記述


④ 各showページに_page_title.html.erbをレンダリング

/app/views/products/show.html.erb
<%= render partial: 'shared/page_title', locals: { page_title: @product.name } %>
# 省略

タイトルに product名-Store が表示されます

/app/views/products/show.html.erb
<%= render partial: 'shared/page_title', locals: { page_title: @category.name } %>
# 省略

同様にタイトルに category名-Store が表示されます

⑤ rspecでhelperのテスト

$ rails g rspec:helper application

Helper specを作成します。
  

spec/helper/application_helper_spec.rb
require 'rails_helper'

RSpec.describe ApplicationHelper do
  describe "#full_title(page_title)" do
    subject { full_title(page_title) }

    context "page_titleが空白の場合" do
      let(:page_title) { "" }

      it { is_expected.to eq("Store") }
    end

    context "page_titleがnilの場合" do
      let(:page_title) { nil }

      it { is_expected.to eq("Store") }
    end

    context "page_titleが存在する場合" do
      let(:page_title) { "sample" }

      it { is_expected.to eq("sample - Store") }
    end
  end
end

先程説明したとおり、引数が空白とnilの場合を考慮しテストします。

参考記事

Qiitaで良い記事を書く技術
Qiita(28)画像の大きさ調整
Markdown記法 サンプル集