ransackとは
Ruby on Railsでシンプルかつ高度な検索フォームを簡単に実装できるgemです。
インストール
公式の手順でインストールしていきます。
gem 'ransack'
$ bundle install
使用方法
Ransackは、シンプルモードとアドバンスドモードの2つのモードで使用できますが、簡単なシンプルモードの使い方を説明します。
例として、記事を検索できる検索フォームを実装します。
コントローラーを編集
まず、検索フォームを実装したいコントローラとそのアクションに以下のコードを記載します。
def index
@q = Post.ransack(params[:q])
@posts = @q.result.includes(:user, :favorites).order(created_at: :desc)
end
Ransack固有のメソッドがいくつかあります。
params[:q]
:後ほど説明する検索フォームでの入力した値を受け取ります。値はハッシュで入っています。
Post.ransack(prams[:q])
:検索フォームの条件、入力した値(params[:q]
)を元に、posts
テーブルからデータを検索します。データの検索条件はオプションで指定できます(公式参照)。
@q.result
:ransack
メソッド取得したデータ(Ransack::Searchオブジェクト
)を元に、ActiveRecord_Relationオブジェクト
に変換します。
ビューを編集
次にviewで検索フォームを作成します。
記事一覧画面で検索したいので、index.html.slim
を編集します。
p 記事検索
= search_form_for @q do |f|
= f.search_field :user_name_cont, placeholder: 'ユーザー名'
= f.search_field :title_cont, placeholder: '記事のタイトル'
= f.search_field :content_cont, placeholder: '記事の内容'
= f.submit
search_form_for
:Railsのフォームヘルパーメソッドであるform_for
、form_with
メソッドのransack版です。
f.search_field
:htmlで<input type="search">
に変換されます。
title_cont
:title
カラムから_cont
という条件で検索するよという条件を指定します(検索するのはコントローラー内)。_cont
は入力した値が含まれる(SQLのWHERE LIKE
)という条件。user_name
(users
テーブルのname
カラム)のように関連のある検索もできます。
@q
:入力した値、条件などの情報が入ります。prams[:q]
で受け取れます。
下記の画像のようなフォームが表示されます。

f.label
でラベルも作成できますが、今回は邪魔だったので、placeholder
を使ってフォームを識別しています。
実装完了
試しに、記事のタイトル
に「test」を入力して、検索してみます。正しく動けば右側の記事のみ表示されます。

ちゃんと検索できています。
動作確認
では、コントローラー内でどのような動きをしているか細かく見ていきます。
まず、コントローラーで検索フォームに入力した検索条件を受け取ります。
params[:q]
#=> <ActionController::Parameters {"user_name_cont"=>"", "title_cont"=>"test", "content_cont"=>""} permitted: false>
params[:q]
には、"title_cont"=>"test"
という検索条件が入っています。
@q = Post.ransack(params[:q])
#=> Ransack::Search<class: Post, base: Grouping <conditions: [Condition <attributes: ["title"], predicate: cont, values: ["test"]>], combinator: and>>
@q
には、title
名に「test」が含まれるpost
(記事)の検索結果がRansack::Searchオブジェクト
で入っています。
<conditions: ~~~~
内に条件が指定されています。
@posts = @q.result
#=> SELECT "posts".* FROM "posts" WHERE "posts"."title" LIKE '%test%' LIMIT ? [["LIMIT", 11]]
#=> <ActiveRecord::Relation [#<Post id: 1, title: "test", content: "テストテスト", post_image: nil, user_id: 1, created_at: "2022-01-02 10:33:30", updated_at: "2022-01-02 10:33:30">
@post
には、@q.result
で@q
の情報からSQLクエリを発行し、その結果がActiveRecord::Relationオブジェクト
で入っています。
ちなみに検索条件が無い場合(nil
)は、Post.all
と同じ動きをします。
検索結果がビューで表示されます。
以上
まとめ
簡単に検索フォームが実装できました。
ここでは紹介できなかったソート機能や詳細設定、多くの検索オプションなどがありますので、一度公式に目を通してみてください。
コメント