【rails6】ransackを用いた複雑検索まとめ


こんにちは!
今日はransackを用いた複雑検索の仕方について纏めていきます

まずは完成形から見てみましょう!

やっていることは
- フォームに入力されたキーワードと商品名で曖昧検索する
- 結果商品を一覧表示させている(今回は一つしかない)
以上です!
今回は簡単な検索機能を実装していきましょう

環境

  • Ruby 2.6.5
  • rails 6.0.0
  • DB: MySQL

参考資料

他様々インターネットで「 rails ransack 使い方 」と検索して出てくる記事はたくさん見ました

① gemをインストールする

まずはransackを導入していきます

gem 'ransack'

→ ターミナルに移り
% bundle install

初期設定はこれでOKです

② どのコントローラーに記述するか決定する

場合によっては限定されたページでの利用も想定されますので、
どの場面で使用するのか」「逆に検索フォームが登場しない場面はいつか
を予め纏めておきましょう

私のアプリは、ほぼ全てのページに検索フォームが登場しますので、「 application_controller.rb 」を使います。
※便利ですが、やはり使用すべき箇所はできる限り限定した方がいいと思います

以下の様に記述をしてください

application_controller.rb
before_action :set_search

private
def set_search
  @q = Item.ransack(params[:q])
  @items = @q.result(distinct: true)
end

ここで、

params[:q]

についてですが、この「 :q 」はデフォルトのキー名ですので、今は変更しない様にしてください

また、

(distinct: true)

この記述をすることで、resultの重複がない様に整えてくれます。
必要がない場合はこの記述は削除してくださいね。

③ルートの設定(必要な人のみ)

次はルートの記述をしていきます。
検索結果を別のページに表示したい!という方向けの手順です。
不要な方は飛ばしてください

下記の様に書いていきましょう

routes.rb
get 'items/search'

これでルートを確認すると、「 items_search_path 」と設定されました。

今後、この「 items_search_path 」を使用していきます。
コピペの際に間違えない様にご注意ください

④検索フォームを作成する

では検索フォームを作成していきましょう
下記は私の一例としてご覧ください

_header.html.erb
<%= search_form_for @q, url: items_search_path, class:"search-form" do |f| %>
  <%= f.search_field :name_cont, placeholder: 'キーワードから探す', class:'input-box' %>
  <%= f.button type: "submit", class:"search-button" do%>
    <%= image_tag "search.png", class:"search-icon" %>
  <% end %>
<% end %>

分解していきます

<%= search_form_for @q, url: items_search_path, class:"search-form" do |f| %>

「 search_form_for 」、これはransackにおいてのフォーム生成タグです。HTMLのform_withと同様です。
@qはコントローラーで生成した変数です。今回はitemsテーブルについての検索をしていきます。
urlには検索結果を表示する先のパスを記述していきます。自由に設定してください。

<%= f.search_field :name_cont, placeholder: 'キーワードから探す', class:'input-box' %>

次の行ですが、
serch_fieldもransack流の書き方ですので、覚えておいてください。
:name_contは、「 itemsテーブルのnameカラムを曖昧検索してください 」という意味になります。
_contはマッチャと呼ばれるオブジェクトで、これは曖昧検索を意味しています。
(参考:_eqにすると完全一致となります。)

他にもたくさんあるので、下記を参考に最適なものをご選択くださいね

ここで、検索キーワードの送信
までは完成しました。

検索結果を表示するために、「 search.html.erb 」を作成し、「 @items 」を表示する記述をしていきましょう。

⑤検索結果を表示する

下記は本当に参考程度に見てください笑

search.html.erb
<%= render "shared/header" %>
<div class='main'>
  <%# 商品一覧 %>
  <div class='item-contents'>
    <div class="item-container">
      <ul class='item-lists'>
        <% if @q.name_cont != nil %>
          <h3 class="subtitle"><%= "#{@q.name_cont} の検索結果" %></h3>
        <% else %>
          <h3 class="subtitle"><%= "検索結果" %></h3>
        <% end %>
        <%= render partial:"item", collection: @items, locals: {item: @item} %>
      </ul>
    </div>
  </div>
  <%# /商品一覧 %>
</div>
<%= render "shared/footer" %>

これで動画と同じ簡単なransack検索機能の実装は完了となります。
次回は複雑検索について書いていきますね
また読んでいってくださいね!!