ransackを使い検索機能を実装する

Ransackとは

ransackとは検索機能を実装するためのgemです。
検索に必要な機能を簡単に実装することができます。

検索機能を実装する利点

一覧画面などでは表示している情報が多いため、必要な情報を探すのに時間がかかってしまいます。
そこで検索機能を実装することで、探す手間を省くことができます。

Ransackの実装の流れ

1. ransackのインストール
2. コントローラーの編集
3. 検索フォーム作成
4. 検索結果の表示


1. ransackのインストール

まずはransackを利用するために、Gemfileに以下の行を追加します。

gem 'ransack'

その後bundleコマンドを実行してransack gem をインストールします。

$ bundle install


2. コントローラーの編集

ransackをインストールすると、検索を行うためのransackメソッドが追加されます。
検索をするためにアクションを追加していきます。

 def index
    @q = current_user.tasks.ransack(params[:q])
    @tasks = @q.result(distinct: true)
  end

上記で使われているメソッドを解説していきます。

params[:q]

params[:q]は、この後に作成するビューファイルから送られてくるパラメーターです。検索フォームで入力した値がこのオブジェクト(@q)に渡されています。

ransack

ransackは、送られてきたパラメーターを元にテーブルからデータを検索するメソッドです。 whrereメソッドのransack版です。

result

resultは、ransackメソッドで取得したデータをActiveRecord_Relationのオブジェクトに変換するメソッドです。
whereは実行結果のオブジェクトを返さないので、取得したデータから特定カラムのデータを取得しようとするとエラーになります。
なので、検索結果を変換する必要があります。

distinct: true

distinct: trueは、検索結果が重複することを防いでくれます。
関連する子テーブルの情報を条件に絞り込んで、親テーブルの検索結果を表示するときには必須となります。
検索時に重複したデータを結果として表示するケースは稀なので、癖としてつけておくほうがいいです。


3. 検索フォーム作成

ransackの提供するヘルパーsearch_form_forを使って検索フォームを追加します。
検索フォームは他ページでも使うため、パーシャル化しておくと便利です。

<%= search_form_for q, class: 'mb-3', url: url do |f| %>
  <div class="input-group mb-3">
    <%= f.search_field :title_or_body_cont, class: 'form-control', placeholder: ("検索ワード") %>
    <div class="input-group-append">
      <%= f.submit class: 'btn btn-primary' %>
    </div>
  </div>
<% end %>

search_form_forメソッドを解説していきます。

search_form_for

search_form_forは、ransackで用意されているヘルパーです。
form_forやform_withのransack版です。

_cont

_contは「名称に〇〇を含む」という検索を実現するためのメソッドです。
LIKE検索を行い、検索ワードで入力された文字が含まれるレコードを取得します。
ransackを利用する際は、検索フィールドを一定のルールで命名する必要があります。


f.search_field

f.search_fieldは、検索フォームの設定をするためのメソッドです。
検索条件の設定などを行います。


4. 検索結果の表示

検索機能を実装したいビューファイルで、作成したパーシャルテンプレート(検索フォーム)を呼び出します。

url: url

呼び出し側で指定したパスをローカル変数に渡すことで、汎用性の高いパーシャルが作れます。

<%= render 'search_form', q: @q, url: tasks_path %>


まとめ

  • ransackは検索機能を簡単に実装できるgem。
  • ransackで提供されているメソッドを使えば、検索条件を簡単に設定できる。


参考にしたサイト

【Rails】 ransackを使って検索機能がついたアプリを作ろう! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト

find、find_by、whereの違い - Qiita