Boring Rails

Tip: Show relevant chunks of text with Rails `excerpt` helper

:fire: Tiny Tips

The Rails helper excerpt can extract a chunk of text that matches a certain phrase, no matter where in the string it is.

Imagine you wanted to display a list of emails matching a certain search term:

Simply filter down your records and then use excerpt on the email body.

Usage

Here’s what your view might look like to build this feature.

<%= link_to email do %>
  <div class="flex justify-between items-center">
    <p class="text-sm font-medium text-gray-900">
      <%= email.sender_name %>
    </p>
    <%= local_time_ago email.received_at %>
  </div>
  <p class="text-sm text-gray-700">
    <%= email.subject %>
  </p>
  <p class="text-sm text-gray-500">
    <%= excerpt(email.body.to_plain_text, params[:q], radius: 15) %>
  </p>
<% end %>

One trick is that if you are using ActionText, call to_plain_text otherwise you might end up with unclosed HTML tags. In general, when you show an excerpt of rich text, you don’t want all of the formatting to be applied anyways.

For bonus points, combine with the Rails highlight helper!

Options

@product.description = "A one-of-a-kind vintange DHH coffee mug signed by the man himself!"

excerpt(@product.description, "coffee", radius: 10)
=> "...tange DHH coffee mug signe..."

This helper is case-insensitive and can accept a string or Regex:

@product.description = "A one-of-a-kind vintange DHH coffee mug signed by the man himself!"

excerpt(@product.description, "COFFEE", radius: 10)
=> "...tange DHH coffee mug signe..."

excerpt(@product.description, /tea|coffee/, radius: 10)
=> "...tange DHH coffee mug signe..."

Options

You can expand the “radius” – or how many characters around the match – are shown. The default is 100.

@product.description = "A one-of-a-kind vintange DHH coffee mug signed by the man himself!"

excerpt(@product.description, "coffee", radius: 5)
=> "...DHH coffee mug..."

excerpt(@product.description, "coffee", radius: 25)
=> "...e-of-a-kind vintange DHH coffee mug signed by the man hi..."

If you need to change the ... into something else, use the omission option.

@product.description = "A one-of-a-kind vintange DHH coffee mug signed by the man himself!"

excerpt(@product.description, "coffee", radius: 10)
=> "...tange DHH coffee mug signe..."

excerpt(@product.description, "coffee", radius: 10, omission: "---")
=> "---tange DHH coffee mug signe---"

excerpt(@product.description, "coffee", radius: 10, omission: "<snip>")
=> "<snip>tange DHH coffee mug signe<snip>"

Additional Resources

Rails API Docs: TextHelper#excerpt

Rails API Docs: ActionText#to_plain_text

If you like these tips, you'll love my Twitter account. All killer, no filler.