掲示板の検索機能の実装

ransackとは?

簡単に検索フォームを作成するためのgem

インストール

Gemfileに

gem 'ransack'

を記載して、bundle install

使い方

使い方はシンプルモードとアドバンスモードの2つがある
今回は、シンプルモードを使って、検索時、掲示板のタイトルまたは本文、ブックマークされた掲示板一覧ページで検索した場合はブックマークした掲示板の中から検索条件に一致したものを表示させるようにする

コントローラ

掲示板一覧(boards_controller.rbのindexアクション)とブックマーク一覧(boards_controller.rbのbookmarkアクション)を以下のように記述

#boards_controller.rb
def index
    @search = Board.ransack(params[:q])
    @boards = @search.result(distinct: true).includes(%i[user bookmarks]).order(created_at: :desc).page(params[:page])
end

def bookmarks
    @search = current_user.bookmark_boards.ransack(params[:q])
    @boards = @search.result(distinct: true).includes(:user).order(created_at: :desc).page(params[:page])
end

params[:q]に検索パラメーターが渡されて、モデル名.ransack(params[:q])と記載することで、@searchと検索オブジェクトが生成される。これに@boards = @search.result(distinct: true)~~と記載することで検索結果を得られるようになる
distinct: trueで取得するデータの重複を取り除いている。これは掲示板と紐づいたコメントなどを検索する場合、同一の掲示板で複数のコメントの検索に引っかかっても、同じ掲示板が複数表示されないようにしてくれる。今回は掲示板だけのカラム検索なので特に必要ない。

ビュー

掲示板一覧(boards/index.html.erb)とブックマーク一覧(boards/bookmarks.html.erb)にそれぞれ以下を記載

#boards/index.html.erb
<%= search_form_for @search do |f| %>
  <div class="input-group mb-3">
    <%= f.search_field :title_or_body_cont, class:"form-control", placeholder: t('defaults.search_word') %>
     <div class="input-group-append">
       <%= f.submit "検索", class: "btn btn-primary" %>
     </div>
   </div>
<% end %>

#boards/bookmarks.html.erb
<%= search_form_for @search ,url: bookmarks_boards_path do |f| %>
  <div class="input-group mb-3">
    <%= f.search_field :title_or_body_cont, class:"form-control", placeholder: t('defaults.search_word') %>
     <div class="input-group-append">
       <%= f.submit "検索", class: "btn btn-primary" %>
     </div>
   </div>
<% end %>

search_form_forform_forの検索フォームバージョンみたいなもの f.search_field :title_or_body_cont, ~掲示板のタイトル(title)と本文(body)カラムに対して、最後の_contでLIKE句を利用した部分一致検索ができるようにしている
複数の属性を検索条件に指定する場合はattribute_name_orattribute_name・・・と記載する この_cont部分を述語(Predicate)と言い、他にも条件と一致したものを検索する_eq
~以上を満たすものを検索する_gteqとかなど様々な検索条件を指定できる述語がある
掲示板一覧とブックマーク一覧の検索フォームビューの違いはurlである それぞれ、検索条件をindexアクションbookmarksアクションに送りたいのでurlでルーティングヘルパーを使って指定している

参考文献

GitHub - activerecord-hackery/ransack: Object-based searching.

Ransackで簡単に検索フォームを作る73のレシピ - 猫Rails