Rails ransackを用いた検索機能

#はじめに
ransackを用いた検索機能の実装です。
ransackは少ないコードで複雑な検索機能を簡単に作れるgemでとても便利です。
この記事はhttps://qiita.com/nakanishi03/items/2a6dbd72f9793b7e0ce4
の続き記事です。こちらも目を通していただけると一層理解が深まります。
読んだらいいねいただけると嬉しいです！！！モチベになります！！！！

#ransackのインストール
Gemfileにransackを追加し、bundle installする。

```ruby:Gemfile
gem 'ransack'
```
```ruby:ターミナル
bundle install
```
#matcherリスト
ransackで作成するフォームには特殊な検索合致キーワード(以下marcher)が存在します。
そのリストの一部をまとめたのでご参照ください。

|matcher      |       意味（のものに合致） | 
|:-----------------|------------------:|
| *_eq          |              等しい |      
| *_not_eq          |            等しくない |     
| *_in           |             配列内の任意の値に一致 |     
| *_lteq              |                以下 |     
| *_gteq         |             以上 |    
| *_start       |           〜ではじまる|  
全リストを参照したい方は以下をご覧ください。
https://github.com/activerecord-hackery/ransack/blob/master/lib/ransack/locale/en.yml#L15

#フォームの作成
今回は①並び替え②名前での検索(searchfield)③値段での検索(searchfield)④状態の検索(checkbox)⑤送信ボタン
の5部構成にしてあります。
クラス名等は適宜変えて自分好みにしてください。

```
.detail_search
  = search_form_for(@q,url: searches_detail_search_path) do |f|
    .detail_search_sort
      = f.select( :sorts, { '並び替え': 'id desc', '価格の安い順': 'price asc', '価格の高い順': 'price desc', '出品の古い順': 'updated_at asc', '出品の新しい順': 'updated_at desc' } , { onchange: 'this.form.submit()'} )
    .detail_search_form
      .detail_search__title
        %h3 詳細検索
      .detail_search__group
        .detail_search__group--label
          = fa_icon "search"
          %p キーワードを追加する
        = f.search_field :name_cont, placeholder: "例）値下げ"
      .detail_search__group
        .detail_search__group--label
          = fa_icon "search"
          %p 価格
        .detail_search__group--forms
          = f.search_field :price_gteq, placeholder: "¥ Min"
          %p 〜
          = f.search_field :price_lteq, placeholder: "¥ Max"
      .detail_search__group
        .detail_search__group--label
          = fa_icon "search"
          %p 商品の状態
        .detail_search__group--checkbox
          %label
            %input{type: "checkbox"}
            = 'すべて'
        .detail_search__group--checkbox
          %label
            = f.check_box :state_in, '1', nil
            = '新品、未使用'
        .detail_search__group--checkbox
          %label
            = f.check_box :state_in, '2', nil
            = '未使用に近い'
      .detail_search__btns
        .detail_search__btn--grey
          = link_to "クリア", "/searches",type: "button"
        = f.submit "完了"
```

<img width="358" alt="スクリーンショット 2019-10-06 17.39.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501638/30437d80-a725-ca1f-c4a5-e5675ac67ace.png">

こんなかんじですね。
入力された値はsearches#detail_searchに送信するように設定しています。ここも適宜変えてください。
#コントローラーの設定

```ruby:searches_controller.rb
class SearchesController < ApplicationController
  before_action :set_ransack

  def detail_search
    @search_product = Product.ransack(params[:q]) 
    @products = @search_product.result.page(params[:page])
  end

private


  def set_ransack
    @q = Product.ransack(params[:q])
  end
  
end
```
これでOKです。
paramsのあたいはハッシュ形式で送られます。
値がうまく取れない場合はデバックして値の受け取り方を変えてみましょう。
それをインスタンス変数に代入すればOKです。

#検索結果の表示

```ruby:searches/detail_search.html.haml

以下はあくまで一例です。
適宜変更してください。

= render 'shared/header'
= render 'shared/sell-btn'
.search
  .search-container
    .search-left
      = render 'searches/form-bar'
    .search-right
      %section.items-box-container
        -if @search.present?
          %h2.search-result-head
            =@search
            %span.search-result-head-text
              の検索結果
          .search-result-number
            ="1-#{@products.count}件表示"
        -else
          %h2.search-result-nil
            検索結果
          .search-result-number
            ="1-#{@products.count}件表示"
        .items-box-content
          = render @products
= render 'shared/footer'
```
0〜６００円で検索してみました。
しっかりできていますね。
<img width="1243" alt="スクリーンショット 2019-10-06 17.53.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501638/6f7aa877-769c-4051-68a7-9f19190e362a.png">

#終わりに
とても簡単ですね。
わからないことがあればコメントしてくだされば答えます！！