超簡単に検索機能が作れるgem - Ransack

demo, gem, rails, ransack

webアプリで検索機能をつけたいときがありますよね。

そこまで最適化されていなくてもいいから機能をつけておきたい、みたいな。

そんなときRailsで使えるgemのRansackの紹介です。

すぐに試してみたいという方はこちら。デモのソースはこちら

Ransack

一言で言えば、リクエストパラメータからsqlを生成するgemです。

RansackはView Helperを持っています。

View Helperが提供する中で重要なのはsearch_fieldとsort_linkで、検索対象のモデルのテーブルが持つカラムに対して、

  • search fieldなら指定されたカラムに対して様々な操作(likeや=など)
  • sort linkならorder by

を生成します。

search_fieldは"#{カラムor関連名}_#{操作}"の形で指定し、params[:q]に、 sort_linkはparams[:q][:s]に格納されます。

1
2
3
4
5
6
7
8
params = {
  'q' => {
    'text_cont' => 'keyword',
    's' => {
      'created_at' => 'desc'
    }
  }
}

また、has manyやbelongs toといったassociation先に対しても指定することができます。

超便利ですね!

Getting Started

おなじみ

Gemfile
1
gem 'ransack'

Controller

検索フォームのリクエスト先であるController側では

1
2
3
4
def index
  @q = Person.search(params[:q])
  @people = @q.result(distinct: true)
end

といったん@qを生成し、検索結果自体はresultで取得します。

@qは検索フォームの状態再現に使用されます。

また、resultの返り値はActiveRecord::Relationのため、includeやmergeなど通常のActiveRecordと同様の扱いが可能です。

View

Ransackはform_forの拡張であるsearch_form_forを提供しています。search_form_forの引数にはcontrollerで作った@qを指定します。

また、search_form_forの中ではsearch_fieldが使用でき、"#{カラムor関連名}_#{操作}"の形で検索フォームを作ることができます。

以下は

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%= search_form_for @q do |f| %>

  # nameが入力テキストを含むレコードを検索
  <%= f.label :name_cont %>
  <%= f.search_field :name_cont %>

  # articles.titleが入力テキストを含むレコードを検索
  <%= f.label :articles_title_start %>
  <%= f.search_field :articles_title_start %>

  # orで複数フィールドを指定できる
  <%= f.label :name_or_description_or_email_or_articles_title_cont %>
  <%= f.search_field :name_or_description_or_email_or_articles_title_cont %>

  <%= f.submit %>
<% end %>

sort_linkに関しては、@qとソートしたいフィールドを指定します。

1
<%= sort_link(@q, :name, 'Last Name', default_order: :desc) %>

簡単ですね!

まとめ

いかがでしたか?

大規模なシステムではDBを直接扱う検索は厳しい物がありますが、自作アプリ等小規模開発やハッカソンなど開発スピードが必要な場面ではRansackは素晴らしいソリューションになりえそうですね!

最後にRansackへのリンクです。

Comments