しおブログ言うてますけど

技術ブログ言うてますけど技術以外のことも発信すると思われ。RubyとかRuby on Railsとか生き方とかジャンルにこだわらず自分の好きなように。初心者なのでお手柔らかに。

ransackで検索機能を実装する

こんにちは、しおはまです。
今回はransackという検索機能を実装できるgemの使い方をまとめてみます。

ransackとは

冒頭で説明した通り、ransackは検索機能を簡単に実装することができるRailsのGemです。
検索機能を実装することで掲示板やToDoアプリ、その他WEBアプリにおいて検索機能が実装されているとなにかと便利です。
それでは使い方をみていきます。

ransackのインストール

まずはGemを使うためにGemfileにransackを追加していきます。

gem 'ransack

Gemfileに追加したらbundle installして準備完了です。

ransackの使い方

まず、コントローラーからみていきましょう。
例として、ユーザーの名前を検索できる機能を実装することを想定し、 users_controllerではこのような形式になってるとしましょう。

# users_controller

def index
  @users = User.all
end

インスタンス変数@usersにUserオブジェクトの全ての値が入っています。
この値を検索できるように下記のように書き換えます。

# users_controller

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

いきなりransackとか(params[:q])とかresultとか出てきて戸惑うかもしれませんが、このメソッドの概要を説明します。

用語 説明
params[:q] ビューファイルから送られてくるパラメーター。
ransackメソッド 送られてきたパラメーターを元にテーブルからデータを検索するメソッド。(whereメソッドのransack版というイメージ。)
resultメソッド ransackメソッドで取得したデータをActiveRecord_Relationのオブジェクトに変換するメソッド。

なんとなくイメージは掴めたでしょうか。
@qの部分は自分で好きな変数名をつけても動きますが、慣習的に@qを使用します。
次に検索をフォームを作っていきます。

# 検索フォーム.erb(例)

<%= search_form_for @q, url: users_path do |f| %>
  <%= f.label :name, "Keyword" %>
  <%= f.search_field :name_cont %>

  <%= f.submit "検索" %>
<% end %>

検索フォームを実装するには<%= %>で囲んでsearch_form_forメソッドを使います。
search_form_forメソッドはransackで用意されているメソッドです。
これがどのようにして検索フォームとしてできているのか。
_contの部分です。
_contはransackで用意されているメソッドで、検索したワードが含まれているレコードを取得するためのメソッドです。
つまり、検索結果に属性(カラム)が含まれていれば表示するというものになります。
ransackには検索のためのメソッドが沢山ようされています。

検索に使えるメソッド

_contのような便利なメソッドの他にたくさんの便利メソッドが用意されているので少し紹介します。

メソッド名 説明
_eq 完全に一致するとき
_not_eq 完全に一致しないとき
_matches 一部が一致するとき
_does_not_match 一部が一致しないとき
_matches_any いずれかに一致するとき
_matches_all 全てに一致するとき
_does_not_match_any いずれにも一致しないとき
_does_not_match_all 全てに一致しないとき
_lt 〜未満のとき
_lteq 〜以下のとき
_gt 〜より大きいとき
_gteq 〜以上のとき
_present nullでも空でもないとき
_blank nullまたは空のとき
_null nullのとき
_not_null nllではないとき
_in 配列内の値と一致するとき
_not_in 配列内のどの値とも一致しないとき
_lt_any いずれかの値より少ないとき
_lteq_any いずれかの値以下のとき
_gt_any いずれかの値より大きいとき
_gteq_any いずれかの値以上のとき
_lt_all 全ての値よりも少ないとき
_lteq_all 全ての値以下のとき
_gt_all 全ての値より大きいとき
_gteq_all 全ての値以上のとき
_not_eq_all 指定した値ではないとき
_start 前方一致のとき
_not_start 前方不一致のとき
_start_any 〜のいずれかで始まるとき
_start_all 〜の全てから始まるとき
_not_start_any 〜のいずれかで始まらないとき
_not_start_all 〜の全てから始まらないとき
_end 後方一致のとき
_not_end 後方不一致のとき
_end_any 〜のいずれかで終わるとき
_end_all 〜の全てで終わるとき
_not_end_any 〜いずれかで終わらないとき
_not_end_all 〜の全てで終わらないとき
_cont 〜の部分が一致するとき
_cont_any 〜のいずれかが含まれているとき
_cont_all 〜の全てが含まれているとき
_not_cont 〜に部分が一致しないとき
_not_cont_any 〜のいずれかが含まないとき
_not_cont_all 〜の全てが含まれないとき
_i_cont 大文字と小文字を区別しない値が含まれるとき
_i_cont_any 大文字と小文字を区別しないいずれかの値が含まれるとき
_i_cont_all 大文字と小文字を区別しない全ての値が含まれるとき
not_i_cont 大文字と小文字を区別しない値が含まれないとき
_not_i_cont_any 大文字と小文字を区別しないいずれかの値が含まれないとき
_not_i_cont_all 大文字と小文字を区別しない全ての値が含まれないとき
_true 真偽値のレコードを取得するとき
_false 真偽値と反対のレコードを取得するとき

長くなってしまいましたがこのようなメソッドが用意されているので、時と場合によって使い分けるようにしましょう。

まとめ

  • コントローラーとビューを変更して、検索機能を実装する。
  • viewファイルではsearch_form_forメソッドを使用する

検索機能は汎用性が高く、よく使われると思うので、いろいろなメソッドを使いこなせるようにしていきたいです。