はじめに
titleタグのタイトルをページ(view)ごとに、異なる内容を表示する方法です。
以下の画像通り、タイトルに「商品名 - Store」が作成できます。
Qiita初投稿のため、分かりにくい点や間違いがあれば指摘をお願いいたします。
到達点
以下の4点を達成する
・products
のshow
ページのタイトルに商品名を表示
「商品名 - Store」
・categories
のshow
ページタイトルに、カテゴリー名を表示
「カテゴリー名 - 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タグ内に
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
</head>
<body>
# 省略
② 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を作成します。
<% provide(:title, page_title) %>
<div class="page-title">
<h2><%= page_title %></h2>
</div>
# 省略
view内にタイトル文と同じ内容の記述が必要であれば、<%= page_title %> と記述
④ 各showページに_page_title.html.erbをレンダリング
<%= render partial: 'shared/page_title', locals: { page_title: @product.name } %>
# 省略
タイトルに product名-Store が表示されます
<%= render partial: 'shared/page_title', locals: { page_title: @category.name } %>
# 省略
同様にタイトルに category名-Store が表示されます
⑤ rspecでhelperのテスト
$ rails g rspec:helper application
Helper specを作成します。
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の場合を考慮しテストします。