11
11

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.

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

Last updated at Posted at 2020-03-15

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

詳しくはニャンコ先生のページが非常に参考になります
Ransackで簡単に検索フォームを作る73のレシピ - 猫Rails

##完成図
image.png

##1Gemfileのインストール

Gemfile
gem 'ransack'

bundle installを忘れずに。

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

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では使えないようです。

検索バー入れたいページの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リンク先の表示用ページ

検索結果を表示したいページの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しました)

検索結果一覧表示画面

一覧ページの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の記述は省くのですが1点、上記のeach文を使うと全ての画像が同じサイズで表示されてしまう欠点がございます。

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

終わりに

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

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

11
11
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
11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?