ransackを使った検索機能の実装

どうもどハマりエンジニアです

 

 

gemの導入

gem 'ransack' → $bundle install

 

要件

  • 掲示板のタイトルor本文の部分一致検索ができること
  • ブックマーク一覧画面で検索した場合はブックマークした掲示板のみが検索対象であること。

 

検索フォームのテンプレートを作成

(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'>
    <%= f.submit value: '検索', class: 'btn btn-primary' %>
  </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'>
    <%= f.submit value: '検索', class: 'btn btn-primary' %>
  </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])

この部分は不要になる。

 

以上でブックマーク一覧の検索も完了!

 

これ以外にも様々な検索が可能なので、場面に応じて適図使用を変えなければいなけい。