ransackによる検索機能の実装

はい、こんばんは。

今回はransackというgemを用いて、検索機能を実装してみようと思います。

ransackのインストール

Gemfile
gem 'ransack'

ターミナル
アプリ名$ bundle install

名称による検索

今回はトップページのindexアクションに検索機能をつけたいので、下記のように記載します。

app/controller/tasks_controller.rb
def index
@q = current_user.tasks.ransack(params[:q])
@tasks = @q.result(distinct: true).recent
end

※この@qは公式ドキュメントに指定してあります。詳しくは下記のREADMENIあります。

github.com

検索フォームの実装

ransackを導入すると、search_form_forというメソッドが使えるようになります。

これは、form_forに変わるヘルパーとして使えますので、form_forの頭にsearch_をつけてください。

ここでは、indexアクションに対して検索フォームを実装して行きます。

名称による検索
qpp/tasks/views/index.html.slim
= search_form_for @q, class: 'hogehoge'
.form-search
= f.label :name_cont, '名称', class: 'hogehoge'
.form-search__name
=f.search_fireld :name_cont, class: 'hogehoge'
.form-group
= f.submit class: 'hogehoge'
登録日時による検索

名称による検索に以下の部分を追加します。

qpp/tasks/views/index.html.slim
= search_form_for @q, class: 'hogehoge'
.form-search
= f.label :name_cont, '名称', class: 'hogehoge'
.form-search__name
=f.search_fireld :name_cont, class: 'hogehoge'
#登録日時による検索
.form-search
= f.label :created_at_gteq, '登録日時', class: 'hogehoge'
.form-search__date
= f.search_field :created_at_gteq, class: 'hogehoge'
#追加完了。indexに検索フォームを追加
.form-group
= f.submit class: 'hogehoge'

検索マッチャー

上記で気になるのが、:namecontと:created_at_gteqではないでしょうか。

これはransackが用意している検索マッチャーと言われるものです。

githubにも上がっていますが、一応意味を説明すると、contでは検索のワードを含むという意味になります。gteqに関してはgreater than or equalと解説があります。

これは、「項目がフォームに入力した値と同じか、それより大きい」を条件として検索してくれます。

ソート機能の実装

変更前

app/views/tasks/index.html.task
・・・・
・・・・
tr
th = Task.human_attribute_name(:name)
th = Task.human_attribute_name(:created_at)
th
tbody
- @tasks.each do |task|
tr
td = link_to task.name,task
td = task.created_at
td
= link_to '編集', edit_task_path(task), class: 'hogehoge'
= link_to '削除', task, method: :delete, data: { confirm:"タスク「task.name」を削除します。よろしいですか?" }, class: 'hogehoge'

これをransakckのヘルパーsort_linkを使って記述を変更します。

sort_linkとは、ソート部分ができる見出しをつ食うことができるヘルパーです。

変更後

app/views/tasks/index.html.slim
tr
th = sort_link(@q, :name)
th = Task.human_attribute_name(:created_at)
th
tbody
- @tasks.each do |task|
tr
td = link_to task.name,task
td = task.created_at
td
= link_to '編集', edit_task_path(task), class: 'btn btn-primary mr-3'
= link_to '削除', task, method: :delete, data: { confirm:"タスク「task.name」を削除します。よろしいですか?" }, class: 'btn btn-danger'

上記のようにth = の部分を変更するだけでソート機能が実装できます。

検索機能は複雑化と思いきや、案外簡単に実装できました。

皆様もお試しください。

それでは。

コメント

タイトルとURLをコピーしました