ransackを使った検索機能の実装
どうもどハマりエンジニアです
gemの導入
gem 'ransack' → $bundle install
要件
検索フォームのテンプレートを作成
(boards/index.html.erb)
<%= search_form_for @search do |f| %>
<div class='form-group mb-3'>
<%= f.search_field :title_or_body_cont,
class: 'form-control', placeholder: '検索ワード' %>
<div class='input-group-append'>
</div>
</div>
<% end %>
- viewからsearch_form_forへ検索ワード入力してEnterを押すと、指定したpathへ送信
- bords_controllerのindexアクションへ送信して検索する
:title_or_body_cont
が検索条件を指定している部分で、マッチャーと呼ばれ、gemでいくつもの種類が用意されている。今回は一部分でも文字が含まれている場合はヒットさせたいので、contを使用している。
controllerを実装
(boards_controller)
def index
# @boards = Board.all.includes(:user)
.order(created_at: :desc).page(params[:page])
@search = Board.ransack(params[:q])
@boards = @search.result(distinct: true).includes(:users)
.order(created_at: :desc).page(params[:page])
end
- フォームから飛んできたデータをparams[:q]で受けて、@searchへ代入(ransackの仕様上、検索パラメータはqを付けて飛ばすようになっている)
- @searchオブジェクトに対して、resultメソッドで検索結果を表示
- 通常indexページは@boards = Board.all.includes(:user).page(params[:page])などと書いていることが多いが、こちら記載は不要になる。
以上で掲示板一覧の検索機能は完成!
ブックマーク一覧での検索
こちらも掲示板一覧とほぼ同じであるが、ここではブックマークをしている掲示板の中から検索したい。
(bookmarks.html.erb)
<%= search_form_for @search, url: bookmarks_boards_path do |f| %>
<div class='form-group mb-3'>
<%= f.search_field :title_or_body_cont,
class: 'form-control', placeholder: '検索ワード' %>
<div class='input-group-append'>
</div>
</div>
<% end %>
ここではurlを指定してあげ、boards_controllerのbookmarksアクションにいくようにする。それ以外は同じ!
(boards_controller.rb)
def bookmarks
@search = current_user.bookmark_boards.ransack(params[:q])
@boards = @search.result(distinct: true).includes(:user)
.order(created_at: :desc).page(params[:page])
# @boards = current_user.bookmark_boards.includes(:user)
.order(created_at: :desc).page(params[:page])
end
ブックマークした掲示板のなかからデータをもってきたいので、@searchはcurrent_user.bookmark_boardsのなかから検索するようにする。
掲示板一覧と同様に最初に記入してあった「
@boards = current_user.bookmark_boards.includes(:user)
.order(created_at: :desc).page(params[:page])
」
この部分は不要になる。
以上でブックマーク一覧の検索も完了!
これ以外にも様々な検索が可能なので、場面に応じて適図使用を変えなければいなけい。