4 comments

[ 3.4 ms ] story [ 19.9 ms ] thread
Somehow this code lacks the magic I‘m used from rails:

    class BooksController < ApplicationController
    def show
        @book = Book.find(params[:id])
        add_breadcrumb("Home", path: root_path)
        add_breadcrumb("Books", path: books_path)
        add_breadcrumb(@book.title)
      end
    end
Only the title is specific to the show method. Home should be set by the application controller and Books by the books controller code.
Here's my preferred approach, with breadcrumbs kept in erb views:

Make this view helper.

    def breadcrumb(&)
      render(layout: 'common/breadcrumb', &)
    end
Add this partial 'common/_breadcrumb.html.erb' (do whatever html you want):

    <li class="breadcrumb-item">
      <%= yield %>
    </li>
Add this to your layout:

    <% if content_for?(:breadcrumbs) %>
      <ol class="breadcrumbs">
        <%= yield :breadcrumbs %>
      </ol>
    <% else %>
Then this is how you use it in your views:

    <% content_for :breadcrumbs do %>
      <%= breadcrumb { link_to 'Foo', foo_url } %>
      <%= breadcrumb { link_to 'Bar', bar_url } %>
      <%= breadcrumb { 'you are here' } %>
    <% end %>
For minitest tests I add this helper:

    module AssertBreadcrumbs
      Crumb = Struct.new(:text, :href)

      # Note: the block must have 1 argument per breadcrumb. It asserts their count.
      def assert_breadcrumbs(&blk)
        assert_select '.breadcrumb-item', blk.parameters.size do |items|
          structs = items.map { |item|
            if (link = item.css('a')[0])
              Crumb.new(link.text, link['href'])
            else
              Crumb.new(item.text.strip)
            end
          }

          yield(*structs)
        end
      end
    end
Which you can use in tests like this:

    assert_breadcrumbs do |item1, item2, item3|
      assert_equal 'Foo', item1.text
      assert_equal foo_url, item1.href

      assert_equal 'Bar', item2.text
      assert_equal bar_url, item2.href

      assert_equal 'you are here', item3.text
      assert_nil item3.href
    end
Idk if there’s something wrong with me but I just can’t look at tailwind classes like that and think yep that looks good to me. Reminds me of the inline php days
Thank God I stopped using Rails.