16
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Ruby on Rails】gem 'ransack' を利用した検索機能/フォームの実装

Last updated at Posted at 2020-02-21

検索機能をgemを使って簡単に実装しましょう!

gem 'ransack'を利用した検索機能実装

Image from Gyazo

インストール

Gemfile

gem 'ransack'

インストールしましょう

ターミナル

$ bundle install

検索機能の作成

application_controller.rb

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ですね

distinct: trueの参考になるページ

検索フォームの作成

検索.html.haml
.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_search
@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を追加します。

route.rb
Rails.application.routes.draw do
  resources :products do
    collection do
      get :search
    end
  end
end

では、検索フォームにurlを追加しましょう

検索.html.haml
.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とコントローラーを記述します。

products_controller.rb
class UsersController < ApplicationController
  def search
  end
end

search.html.haml
= 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に書き換えれば、出来上がりです。

まとめ

検索処理は下記だけ

application_controller.rb

before_action :set_search
def set_search
  @search = Product.ransack(params[:q]) #ransackの検索処理
  @search_products = @search.result # 検索結果
end

検索フォームを作って

検索.html.haml
.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で作るシンプルな検索機能のテンプレ

16
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?