LoginSignup
1
1

More than 3 years have passed since last update.

Rails:パンくずリストに2ページ目以降に「Xページ」と表示する方法

Posted at

ページネーション機能がある一覧表示ページのパンくずリストに、「Xページ目」と表示するための実装方法を紹介します。

テキストだとちょっと伝わりづらいですが、

  • 1ページ目ならばページ名
    ScreenShot 2020-06-28 15.19.19.jpg

  • 2ページ目ならばページ名 > #{ページ数}ページ目
    ScreenShot 2020-06-28 15.16.04.jpg

のように、「1ページ目と2ページ目以降でことなる表示」にし、「2ページ目以降にはページ数を表示する」、ということを今回の仕様とします。

環境

自作のプロテイン口コミサービスに導入( https://github.com/yuki0920/supplebox )のアイテム一覧ページ(/products/index)に導入すること前提に説明します。

また、ページネーション機能はkaminariで、パンくずリスト機能はgretelですでに実装されていることを想定しています。

# Gemfile
gem 'kaminari'
gem 'gretel'

現状

1ページ目でも2ページ目以降でもページ名(アイテム一覧)が表示されています。

ScreenShot 2020-06-28 15.19.19.jpg

gretelのオーソドックスな使い方をしています。

config/breadcrumbs.rb
crumb :products do
  link 'アイテム一覧', products_path
  parent :root
end
app/views/products/index.html.haml
- breadcrumb :products

Xページ目を表示する

設定ファイルに追記します。parentにproductsを設定します。ページ数をpageとして第2引数で受け取り、
pageを使ってページ数を表示するようにします。

第2引数で受け取った値を表示できる、というのはREADMEのサンプル集に載っています。

config/breadcrumbs.rb
crumb :products do
  link 'アイテム一覧', products_path
  parent :root
end

# 追記
crumb :products_pagination do |page|
  link "#{page}ページ目"
  parent :products
end
app/views/products/index.html.haml
- breadcrumb :products_pagination params[:page]

呼び出し元のViewテンプレートでは、breadcrumbメソッドの引数に注目です。

  • 第1引数に、products_pagenation
  • 第2引数に、params[:page]

kaminariでは、ページ数がクエリパラメータとして渡ってきます(例えば、/products?page=2)ので、params[:page]でページ数を取得して第2引数として渡すのです。

このようにすることで、1ページ目も2ページ目以降もパンくずリストにページ数を表示することができました。

が、1ページ目のときには問題があります。

params[:page]がnilのため、Home › アイテム一覧 › ページ目の表示になってしまいます。

1ページ目と2ページ目以降で場合分けをする

ということで、param[:page]の値を使って、1ページ目と2ページ目以降で場合分けをします。

app/views/products/index.html.haml
- if params[:page].nil? || params[:page] == 1
  = breadcrumb :products
- else
  = breadcrumb :products_pagination, params[:page]

これで、当初の目標を満たすことができました。

  • 1ページ目ならばページ名
  • 2ページ目ならばページ名 > #{ページ数}ページ目

とはいえ、Viewファイルがごちゃっとしているのが気になります。

リファクタリング

ロジックをViewファイルに書くと見通しが悪くなってしまうので、メソッド化してヘルパーに切り出します。

app/helpers/application_helper.rb
def breadcrumb_pagination
  if params[:page].nil? || params[:page] == 1
    breadcrumb :products
  else
    breadcrumb :products_pagination, params[:page]
  end
end

呼び出し元もヘルパーに定義したメソッドに修正します。
以上で完了です。

app/views/products/index.html.haml
- breadcrumb_pagination

補足(System Spec)

パンくずリストの実装に関して下記のようなテストを書いて仕様を担保しました。
パンくずリストに関わる実装のみを抜粋しているので、雰囲気だけでも伝えられれば。

やはり、テストを書くとリファクタリングがはかどりますね!

spec/system/products_spec.rb
# frozen_string_literal: true

require 'rails_helper'

describe 'アイテム', type: :system do
  describe '一覧機能' do
    before do
      create_list(:product, 13)
    end

    it 'ユーザーはアイテム一覧を閲覧できること' do
      visit products_path
      expect(page).to have_content 'Home › アイテム一覧'
      expect(page).to_not have_content 'Home › アイテム一覧 › 1ページ目'
      expect(page).to have_selector '.pagination'
      within '.pagination' do
        click_link '2'
      end
      expect(page).to have_content 'Home › アイテム一覧 › 2ページ目'
      within '.breadcrumbs' do
        expect(page).to have_link 'アイテム一覧' ,href: products_path
      end
    end
  end
end
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1