Boring Rails

Tip: Use the Rails helper `highlight` when showing search results

:fire: Tiny Tips

Use the Rails highlight helper to wrap search result matches in <mark> tags.

Rails highlight helper

Highlight the search term “comment” in a list of notifcations

Usage

Pass the search term to your controller via params (e.g. params[:search]) and use that to filter down your results.

# app/controllers/inbox_controller.rb
class InboxController < ApplicationController
  def index
    @notifications = Current.user.notifications.for_search(params[:search])
  end
end

# app/models/notification.rb
class Notification < ApplicationRecord
  belongs_to :recipient, class_name: "User"

  validates :message, presence: true

  def self.for_search(term)
    if term.present?
      # Implement searching however you'd like
      where("message ILIKE ?", "%#{term}%")
    else
      all
    end
  end
end

Render the notifications and use TextHelper#highlight on the message to emphasis the matching query.

<% @notifications.each do |notification| %>
  <%= link_to highlight(notification.message, params[:search]), notification %>
<% end %>

You can style the <mark> tag however you’d like.

mark {
  background-color: yellow;
}

Options

You can pass either a string, array, or a regex as the phrase to match. Matches are case-insensitive.

highlight('Boring Rails is the best', 'rails')
# => Boring <mark>Rails</mark> is the best

highlight('Boring Rails is the best', /rails|best/)
# => Boring <mark>Rails</mark> is the <mark>best</mark>

highlight('Boring Rails is the best', ['is', 'best'])
# => Boring Rails <mark>is</mark> the <mark>best</mark>

If there are no matches or you leave the phrase blank, everything still works fine.

highlight('Boring Rails is the best', 'JavaScript')
# => Boring Rails is the best

highlight('Boring Rails is the best', '') # nil works too
# => Boring Rails is the best

You can also override the HTML markup wrapped around the matches using the highlighter option. Use \1 to reference the match. The output is sanitized by default

highlight('Boring is best', 'best', highlighter: '<b>\1</b>')
# => Boring is <b>best</b>

highlight('Boring is best', 'best', highlighter: '<a href="tagged?q=\1">\1</a>')
# => Boring is <a href=\"tagged?q=best\">best</a>

If you need to run additional code, you can pass a block to render instead.

highlight('Blog: Boring Rails', 'rails') do |match|
  link_to(match, public_share_path(term: match))
end
# => Blog: Boring <a href="/public/share?term=Rails">Rails</a>

Additional Resources

Rails API Docs: TextHelper#highlight

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