検索機能をgemを使って簡単に実装しましょう!
gem 'ransack'を利用した検索機能実装
インストール
gem 'ransack'
インストールしましょう
$ bundle install
検索機能の作成
before_action :set_search
def set_search
@search = Product.ransack(params[:q]) #ransackの検索メソッド
@search_products = @search.result(distinct: true).order(created_at: "DESC").includes(:user).page(params[:page]).per(5) # productsの検索結果一覧
# 最終的に、@search_productsを検索結果画面(例:search.html.haml)に挿入します。
# 検索結果の一覧: @search_products = @search.result.order(created_at: "DESC")
# distinct: trueは検索結果のレコード重複しないようにします。
# ページネーション: .includes(:user).page(params[:page]).per(5
end
application_controller.rbで定義します。
products_controller.rbに書くとproducts_controller.rbを使わないページを表示した時にエラーになるため、application_controller.rbで記述。
kaminariでページネーションをつけているのでpage(params[:page])をつけた。
searchメソッドよりransackメソッド推奨なのでransackメソッドを使った。
ransackの検索オプション
検索方法 | 意味(英語) | 意味 |
---|---|---|
*_eq | equal | 等しい |
*_not_eq | not equal | 等しくない |
*_lt | less than | より小さい |
*_lteq | less than or equal | より小さい(等しいものも含む) |
*_gt | grater than | より大きい |
*_gteq | grater than or equal | より大きい(等しいものも含む) |
*_cont | contains value | 部分一致(内容を含む) |
今回使ったのは*_contですね
検索フォームの作成
.search_wap
= search_form_for @search do |f|
= f.text_field :name_cont , placeholder: "何かお探しですか?", class: 'input'
= button_tag type: 'submit', class: 'search__button' do
.icon_wap
%i.fas.fa-search
haml形式でフォームを作成した。
この段階では、url:〇〇_pathはつけていません。あとで付与していきます。
scssのmixinも記載しておきます。
@mixin input{
border: none;
border-radius: 50px;
background: #F4F8F9;
height: 37px;
width: 100%;
padding: 10px 20px;
}
.search_wap{
margin-right: 15px;
position: relative;
.input{
@include input;
margin: 13px 0 0;
}
.search__button{
background-color: transparent;
cursor: pointer;
position: absolute;
right: 0px;
top: 13px;
height: 37px;
width: 40px;
border-style: none;
border-radius: 0px 4px 4px 0px;
padding: 0px;
.icon_wap{
i{
position: absolute;
right: 14px;
top: 13px;
font-size: 13px;
font-weight: 900;
color: #999999;
}
}
}
}
検索結果のview作成
あとは、検索画面を作成して、検索結果である@search_productsを挿入してあげれば完成です。
検索結果用の画面に移行するために、route.rbにget :searchを追加します。
Rails.application.routes.draw do
resources :products do
collection do
get :search
end
end
end
では、検索フォームにurlを追加しましょう
.search_wap
= search_form_for @search, url: search_users_path do |f|
= f.text_field :name_cont , placeholder: "何かお探しですか?", class: 'input'
= button_tag type: 'submit', class: 'search__button' do
.icon_wap
%i.fas.fa-search
view用のhtml.hmlとコントローラーを記述します。
class UsersController < ApplicationController
def search
end
end
= render 'shared/main-header'
.container-fluid
.row.py-5.w-100
.jscroll
= render partial: 'user', collection: @search_products, as: "product", class: "jscroll"
// @search_productはapplication_controller.rbで定義している。
@search_productで検索結果のProductを表示させるので、indexで作成したviewに@productsを@search_productに書き換えれば、出来上がりです。
まとめ
検索処理は下記だけ
before_action :set_search
def set_search
@search = Product.ransack(params[:q]) #ransackの検索処理
@search_products = @search.result # 検索結果
end
検索フォームを作って
.search_wap
= search_form_for @search do |f|
= f.text_field :name_cont , placeholder: "何かお探しですか?", class: 'input'
= button_tag type: 'submit', class: 'search__button' do
.icon_wap
%i.fas.fa-search
あとはviewに@search_productsを挿入すれば完成。
if文を追加する
if文を追加するなら、下記の3パターンがいいかもしません
// 検索キーワードなし: 空白だとスペースを入れいてるname全部がヒットしてしまうため
- if params[:q]['name_cont'] == ""
= "検索キーワードがありません。"
// 検索結果ありの場合
- elsif @search_products.present?
= "「#{params[:q][:name_cont]}」の検索結果: #{@search_products.count}個"
// 検索数0の場合
- else
= "検索に一致する商品はありませんでした"
では実際に書いていきましょう!
複数カラムでの検索方法
複数キーワードをANDで検索する
参考リンク
ransackでRailsアプリのヘッダーに検索機能をつける
【Rails】ヘッダーへの検索機能の付け方
Rubyon Rails で検索機能を作ろう(ransack)
[Rails]ransackを利用した色々な検索フォーム作成方法まとめ
Rails 5.1とBootstrapで作るシンプルな検索機能のテンプレ