ransackで検索フォームを実装

今回は検索フォームを実装したいと思います。

Image from Gyazo

こちらが完成品です。
掲示板のタイトルか本文にワードが含まれていたら検索結果を一覧で表示させるようにします。

ransack

ransackとは簡単に検索機能を実装できるgemです。

インストール

まずはGemfileに

gem 'ransack'

を加えてbundle installします。

コントローラーを編集

class BoardsController < ApplicationController
  def index
    @q = Board.ransack(params[:q])
    @boards = @q.result(distinct: true)
  end

ransackメソッド送られてきたパラメーターを元にテーブルからデータを検索するメソッド
params[:q])検索パラメータを取得
resultメソッドransackメソッドで取得したデータをオブジェクトに変換するメソッド
(distinct: true)検索結果の重複を取り除く

ビューを作成

検索フォームは他のページにも使いたいので部分テンプレート化しておきます。

<!-- _search_form.html.erb -->

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

ransackで用意されているsearch_form_forでフォームを作りましょう。
フォーム部分はf.search_fieldとすることで検索用のフォームとして作ることができ、type='search'が付与されます。
こうすることでフォームにxボタンが付き、表示内容を削除できます。

Image from Gyazo

あとは表示させたいところでrenderしてあげるだけです。

<!-- app/views/boards/index.html.erb -->

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

q:@qurl: urlの部分は、ローカル変数に値を渡すことで汎用的に使えるようにしています。

_contもransackで用意されているメソッドで、検索したワードが含まれているレコードを取得するものです。
title_or_body_contのように_or_で繋ぐことでtitleカラムとbodyカラムにワードが含まれているか検索してくれます。

検索の仕方は他にも色々メソッドがありそれぞれ出来ることが違うので気になる方は調べてみてください。

最後に

検索機能はほぼ必須というくらい、どんなサービスでも見かけるものだと思います。
複雑なものになってくるとちょっとどうかわかりませんが、これくらいの検索機能ならransackを使えば簡単に実装できますね。
この記事が参考になれば幸いです。