掲示板の検索機能を実装
ransackで検索機能を実装する
ransackとは、簡単に検索フォームを作成できるgem
Gemfile
gem 'ransack'
bundle install
コントローラーの修正
今回検索フォームを配置する、掲示板一覧(index)とお気に入り一覧(bookmarks)部分を修正していく。
app/controllers/boards_controller.rb
class BoardsController < ApplicationController def index @q = Board.ransack(params[:q]) @boards = @q.result(distinct: true).includes(:user).page(params[:page]) end def bookmarks @q = current_user.bookmark_boards.ransack(params[:q]) @boards = @q.result(distinct: true).includes(:user).page(params[:page]) end
params[:q]でフォームで検索入力した文字列を取ってくる。
@q.resultで検索結果を渡している。 distinct: trueオプションを使えば、結果の重複を防ぐことができる。
includes 何度もSQLを発行するN+1問題が起こらないように、関連するデータも含めて取得している。
View
それぞれのアクションでは異なるViewファイルを表示しますが、「検索フォーム」は共通
app/views/boards/_search_form.html.erb
<%= search_form_for q, url: url do |f| %> <div class="input-group mb-3"> <%= f.search_field :title_or_body_cont, class: 'form-control', placeholder: '検索ワード' %> <div class="input-group-append"> <%= f.submit '検索', class: 'btn btn-primary' %> </div> </div> <% end %>
ansackのsearch_form_forヘルパーを使用します。
第一引数に、先程定義した検索オブジェクトqを渡します。
urlオプションを設定し、リクエストするUrlを指定する。
今回は指定対象がbookmarks_boards_pathだけだったので、検索フォームからrenderするときにurlを渡しているが、 同じ検索フォームを使い回しし、ページによって検索対象が変わるときには、url: request.path_infoと渡す。
パーシャルファイルの_search_form.html.erbをrenderする各所で、ローカル変数に値を渡す。 app/views/boards/index.html.erb
<%= render 'search_form', q: @q, url: boards_path %>
app/views/boards/bookmarks.html.erb
<%= render 'search_form', q: @q, url: bookmarks_boards_path %>
参考文献