ransackで検索機能実装　全然簡単じゃなかった。。。

理解をしていないことを始めようという時に
これは簡単なはずだーと決めつけて初めてしまうのはよくないですね。はい

詳しくはニャンコ先生のページが非常に参考になります
[Ransackで簡単に検索フォームを作る73のレシピ - 猫Rails](http://nekorails.hatenablog.com/entry/2017/05/31/173925)

##完成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/6d74638a-ae42-5740-2952-88f70ad0854e.png)

##1Gemfileのインストール
```ruby:Gemfile
gem 'ransack'
```
`bundle install`を忘れずに。

##2コントローラーへの記述
ざっくりいうと２パターンあります
①他のページにも検索画面が出る場合（例えばヘッダーに検索が入ってて他のページにリンクしてもヘッダーはそのまま残るとかのケース）
この時は`application_controller`に記述しましょう
②他のページには影響ないよーって時は関係のあるcontrollerに書いておけば動きます。
自身は①のパターンだったので`application_controllere`に記述しました。
最初は２に記載して`No Ransack::Search object was provided to search_form_for!`というエラーに苦しめられました。

```ruby:application_controllere
  before_action :set_search
#中省略
  def set_search
#以下は検索に使うときの記述（変数やモデル名は変更してもいいですが
#".ransack(params[:q])"はそのままで使用します。）
    @search = Item.ransack(params[:q])
 
#以下は検索したものを表示する時に使う記述(一番シンプルで基本の形です)
    @items = @search.result
  end
```
##3検索フォームを記述
書き方はraansack用があるので、form_forやform_tag,form_withでは使えないようです。

```ruby:検索バー入れたいページのhaml
#ここの@searchは上記controllerで指定した検索用の変数を入れてください
        = search_form_for@search,url: 行きたいページの_path do |f|
          = f.search_field :name_cont,class:'search',placeholder: '何かお探しですか？'
          = button_tag type:'submit',class:'btn' do
            = image_tag"search-solid.svg",class: 'btn'
```
今回はsubmitを画像に置き換えたかったのでこの書き方をしていますが
普通にf.submitでOKです。

= f.search_field :以降の`name_cont`はどのカラムの検索条件かを指定しています。
今回自身は
controllerの@searchでItemテーブルを指定していたのでItemテーブルにある`name`カラムの`cont`＝`一部一致`になったものを検索してurlで指定したページへ持っていくよう実装しています。

##4リンク先の表示用ページ

```ruby:検索結果を表示したいページのhaml
.search
  .search-container
    .search-left
      = render #ここには詳細検索用のページを入れ込んでいますが今回は省きます
    .search-right
      %section.items-box-container
        -if @search.present? #@searchで検索した文字を持っってきます
          %h2.search-result-head
          - @items.each do |item|　#表示をする時はcontrollerで指定した変数を使います
            = item.name
            %span.search-result-head-text
              の検索結果
          .search-result-number
            ="1-#{@items.count}件表示"
        -else
          %h2.search-result-nil
            検索結果
          .search-result-number
            ="1-#{@items.count}件表示"
        .items-box-content
          = render #検索結果の一覧を表示するページ（今回は文字ではなく複雑に組んである画像とかだったのでrenderしました）
```

***検索結果一覧表示画面***

```ruby:一覧ページのhaml
.category-items
  .category-items__item
    - @items.each do |item| #今回は複数画像表示しなければ行かなかったのでeachを使用しています
      .category-items__item__link
        = link_to item_path(item.id) do
          %figure.category-items__item__figure
            .category-thumbnail
              .category-itemsprice{aria: "", label: ""} 
                = "¥#{item.price}"
              = image_tag "#{item.images[0].src}", alt: 'category-item',class: 'category-image'
              %figcaption.category-items 
                = item.name
#以下は売り切れた商品の時に表示が出るようにしているだけなので記載なくても大丈夫です。
              -if item.buyer_id.present? 
                .items-box_photo__sold
                  .items-box_photo__sold__inner
                    SOLD

```
今回、scssの記述は省くのですが１点、上記のeach文を使うと全ての画像が同じサイズで表示されてしまう欠点がございます。

####scssで解決方法
2種類くらいあり`直下セレクタ`というものもあるようですが今回は
`:nth-chil`というのを使用しました。何か（今回は画像だったのでimg）の何番目のものに対してのみscssを当てるというものです。

## 終わりに
急いでぎゅっと作成したのでまだまだ理解が浅いのですがransackですが、コード自体の記述は少なくて済みますし、煩雑にならずいい面があります！
が、理解が足りないとドツボにはまるgemでした。。。
商品詳細に関してはまだまだ実装部分に研究の余地がございますので、もう少し形になるようでしたら記事にしたいと思います。

最後まで読んでいただきありがとうございます。
初学者ですので不備やアドバイスなど頂けると幸いです。