Railsでパンくずリストを実装するためにbreadcrumbs_on_railsを使ってみた
最近、Rails アプリでパンくずリストをいい感じに実装するために、breadcrumbs_on_railsという Gem を使用してみました。
すでにネット上に使ってみた的な記事はちらほら見受けられましたが、自分なりにどのように使ったかなどを書いておきたいと思います。
breadcrumbs_on_rails の基本的な使い方
以下のように Controller 側でadd_breadcrumbメソッドを呼んでおくと、呼び出した順に@breadcrmbsに要素がセットされるようになっている。
class PostsController
add_breadcrumb 'ホーム', :root_path
add_breadcrumb '投稿一覧', :posts_path
def index
@posts = Post.all
end
end
後は View 側でrender_breadcrumbsメソッドを呼べば、@breadcrumbsの中身をもとにBreadcrumbsOnRails::Breadcrumbs::SimpleBuilderが要素をレンダリングしてくれるようになっている。html_safeもしてくれているし、separatorを渡すこともできる。
body = render_breadcrumbs, separator: '>'
でもこのレンダリングは単純にアンカーリンクを生成して ERB で吐いているだけなので、やはりマークアップ自体をカスタマイズしたいという欲求が出てくる。
これはBreadcrumbsOnRails::Breadcrumbs::Builderを継承した独自 Builder を定義して、そいつのrenderメソッドを実装することで出来そう。
パンくずリストのマークアップをカスタマイズする
以下のような Builder をconfig/initializers以下に定義して、自分が使いたいテンプレートを使えるようにした。
module BreadcrumbsOnRails
module Breadcrumbs
class MyBuilder < Builder
# 元々protectedで定義されているが、View側で使いたかったのでpublicにしてる
public :compute_name, :compute_path
def render
# 使いたいテンプレートのパスを指定する
@context.render '/layouts/breadcrumbs', elements: @elements, builder: self
end
end
end
end
/ Slimです
- if elements.present?
nav
ul
- elements.each do |elem|
- name = builder.compute_name elem
- path = builder.compute_path elem
li
- if path.present?
= link_to_unless_current name, path
- else
= name
ホームへのリンクなど、ほぼ全ての画面で必要なリンクを ApplicationController で定義する
今回、例えば投稿詳細画面にホーム < 投稿一覧 < Awesome post!(投稿詳細)みたいなリストが表示されるようなケースを想定していて、この中のホームはホーム画面以外の全画面で必要になることが予想される。
このような処理はとりあえずApplicationControllerにホームリンク用のadd_breadcrumbを書いてしまって、パンくずリストを表示したくない画面の Controller 内で@breadcrmbsを消し去るメソッドを呼ぶようにしてみる。
class ApplicationController < ActionController::Base
add_breadcrumb 'Home', :root_path
def remove_breadcrumbs
@breadcrumbs = nil
end
end
class HomeController < ApplicationController before_action :remove_breadcrumbs end
Symbol で指定できないパスを指定する
root_pathのようなパスではなく、post_path(@post)のようなものを指定したい場合の話。一例として、画面設計は完全に適当だけど、ホーム < 投稿一覧 < Awesome post!(投稿詳細)< コメント一覧みたいなものをコメント一覧画面で表示したいとすると、以下のようにすれば指定できる。
module Posts
class CommentsController
add_breadcrumb '投稿一覧', :posts_path
before_action :add_post_breadcrumb
add_breadcrumb 'コメント一覧', :post_comments_path
def index
@comments = Comment.all
end
private
def add_post_breadcrumb
add_breadcrumb @post.title, view_context.post_path(@post)
end
end
まとめ
breadcrumbs_on_rails という Gem は実装も小さいし、特に不満なく使えました。
実際「フルスクラッチでパンくず表示リストを表示する仕組みを実装するぞ」ってなったとしても、結局 breadcrumbs_on_rails みたいな実装になってしまう気もするので、Rails でパンくずリストを実装したい人はガンガン使っていけば良いのではないでしょうか。