Boring breadcrumbs for Rails
Tags: ruby, rails, webdev
Published: 2021-03-12 14:51:07

---
title: Boring breadcrumbs for Rails
published: true
date: 2021-03-12 13:00:00 UTC
tags: ruby,rails,webdev
canonical_url: https://boringrails.com/tips/boring-breadcrumbs-rails
---

Breadcrumbs are a common UI pattern in most software applications. Rails has no built-in tools specifically for breadcrumbs, and while [there](https://github.com/fnando/breadcrumbs) [are a](https://github.com/piotrmurach/loaf) [handful](https://github.com/lassebunk/gretel) [of existing](https://github.com/zachinglis/crummy) [gems](https://github.com/weppos/breadcrumbs_on_rails), I think this is something you can easily implement in your own app with just a few lines of code.

Ultimately, you’ll want control of how you display the breadcrumbs in your app so you might as well just own all the code for this functionality.

## Usage

First, add a model for a `Breadcrumb`. This can live in the `app/models` folder but does not need to be an ActiveRecord model since we don’t need it to persist to the database.

```ruby
class Breadcrumb
  attr_reader :name, :path

  def initialize(name, path)
    @name = name
    @path = path
  end

  def link?
    @path.present?
  end
end
```

Next add a method to your `ApplicationController` to store and add breadcrumbs.

```ruby
class ApplicationController < ActionController::Base
  ...

  helper_method :breadcrumbs

  def breadcrumbs
    @breadcrumbs ||= []
  end

  def add_breadcrumb(name, path = nil)
    breadcrumbs << Breadcrumb.new(name, path)
  end
end
```

Then in your layout, you can render the breadcrumbs however you’d like. In my applications, I use the breadcrumbs in both the `<title>` head tag and in the page header.

```erb
<head>
  <title>
    <%= breadcrumbs.map(&:name).reverse.append("My App").join(" | ") %>
  </title>
</head>

<nav>
  <ol class="breadcrumbs">
    <% breadcrumbs.each do |crumb| %>
     <li>
      <% if crumb.link? %>
        <%= link_to crumb.name, crumb.path, class: "breadcrumb-link" %>
      <% else %>
        <span class="breadcrumb-page">
          <%= crumb.name %>
        </span>
      <% end %>

      <% unless crumb == breadcrumbs.last %>
        <span class="breadcrumb-separator">/</span>
      <% end %>
     </li>
    <% end %>
  </ol>
</nav>
```

It’s a simple API, but this model will allow you to add breadcrumbs in each of your controllers. The breadcrumb can include an optional `path` if you want it to be a link.

You can setup breadcrumbs in `before_actions` or inside each action. You can add conditional logic just like with any regular Ruby code.

```ruby
class PostsController < ApplicationController
  before_action :set_breadcrumbs

  def index
    @posts = Post.all
  end

  def show
    @post = Post.find(params[:id])

    add_breadcrumb(@post.title, @post)
  end

  def new
    @post = Post.new

    add_breadcrumb("New Post")
  end

  private

  def set_breadcrumbs
    add_breadcrumb("Admin", admin_home_path) if Current.user.admin?
    add_breadcrumb("Posts", posts_path)
  end
end
```

Sexy? No. Boring? Yes. Works great? Of course.

* * *
[![](https://boringrails.com/images/twitter-banner.png)](https://twitter.com/_swanson)