某フリマサイトの検索まとめ(前編)

某フリマサイトのコピーをRailsにて作成した際にransackによる検索をする方法をまとめました

URL:https://github.com/yusuke-ishizaki/freemarket_sample_50b


Ransackによる条件検索


——————————————————
・必要なもの
Gem”ransack” gem”active hash”


—————————————————
・詳細検索作成手順
1. ransack 導入
2. コントローラー記述
3. フォーム制作
4. ActiveHash導入(gem,モデル)
5. ActiveHash導入(アソシエーション)
6. フォーム作成2
↓詳細

————————————————

1. Ransack 導入
gemfileに gem’ransack’記述
→bundle install
rails s

 


2.コントローラーに記述
検索対象コントローラーにsearchアクションを作成
今回は ’products controller’
→検索オブジェクト作成
@search = Product.ransack(params[:q])
・@search…検索オブジェクト、検索するということの定義、名前なんでも良き
・.ransack…Productのデータを検索するよーという命令メソッド
・params[:q]…検索結果パラメータ、公式より:qにするみたい
→検索オブジェクト結果作成
@products = @search.result
・@products…検索結果オブジェクト、結果の定義、こっちをviewに反映する、名前なんでも良き
・.result…resultメソッド、検索オブジェクトの検索結果を出力する
→まとめ
class ProductController < ApplicationController
def search
@search = Product.ransack(params[:q])
@products = @search.result
end
●[product_controller.rb L64]
<おまけ>distinct: trueや.to_a.uniqを使うことで重複を避けることができる
@search.result(distinct: true) @search.result.to_a.uniq

 

3.フォーム雛形作成
通常の入力・検索フォームではform_with, form_for, form_tag使う”search_form_for”を用いる
“= search_form_for 検索オブジェクト, url: 検索結果表示ページのpath do |f| “
検索オブジェクトにはcontrollerで定義したもの(今回は@search)を用いる
パスは url: で結果表示先を示す
|f| はform_with系と同様に f.label のように使う
今回は “= search_form_for @search, url: search_product_index_path do |f|”
●[search.html.haml L5]
<おまけ> “= search_form_for(@q, format: :pdf) do |f|” “= search_form_for(@q, format: :json) do |f|” とすることで形式をpdfやjsonに指定できる


キーワード検索フォーム ransack版
“= search_form_for 検索オブジェクト, url: 検索結果表示ページのpath do |f| “のネスト中に
“= f.search_field :カラム_cont, class:クラス名”
search_field…検索入力バーを作成する
カラム_cont…指定カラムに対してLIKE句検索(あいまい検索)を行う
今回は “= f.search_field :name_cont, class: "search-box__detail-search__form-group__input"
●[search.html.haml L15]
★今回name_contとした理由…controllerで@search=Product.ransack とProductモデルに検索をかけるよう指定しているので “nameカラム”に”_cont”しても正確にProduct.nameを検索する(Brand.nameなど他のモデルには手を出さない)
<おまけ>複数カラムあいまい検索…= f.search_field :カラム1_or_カラム2_or_カラム3_cont(orのとこandでもおっけい) 1にname、2にstatus、3にtextなど

 

検索結果表示

- @products.each do |product|

検索結果の表示には、controllerにて定義した検索結果オブジェクト@products

 

 

検索結果をソートさせたい

= sort_link(検索オブジェクト, :カラム, ‘ソートのラベル’, default_order: :desc)”

今回は”= sort_link(@search, :name, '名前順', default_order: :asc)”

[search.html.haml L6]

 

 

価格帯検索したい

= f.number_field :カラム_gteq, placeholder: 説明, class:クラス名”

= f.number_field :カラム_lteq, placeholder: 説明, class:クラス名”

_gteq で~以上の検索

    _lteq で~以下の検索

今回は

= f.number_field :price_gteq, placeholder: " Min", class: "search-box__detail-search__form-group__price-min search-box__detail-search__form-group__input””

= f.number_field :price_lteq, placeholder: " Max", class: "search-box__detail-search__form-group__price-max search-box__detail-search__form-group__input””

[search.html.haml L32]

 

 

 

—————————————————————

追記

今回使わなかったけどransackでできること

Predicate検索(カラム名と述語(Predicate)で検索する方法)

*_eq   equal(=)を使った検索

*_matches    LIKE検索

*_does_not_match    LIKE検索で除外されるもの

*_cont   LIKE検索(部分一致)

*_start   LIKE検索(前方一致)

*_end   LIKE検索(後方一致)

*_gt   より大きい(>)検索

*_gteq   以上(>=)検索

*_lt   より小さい(<)検索

*_lteq   以下(<=)検索

*_true  trueのものを検索

*_false   falseのものを検索

*_null    null(存在しない)ものを検索

*_present   present?メソッドに近い NULLでも空文字でもなければマッチ

*_blank      blank?メソッドに近い  NULLか空文字だったらマッチ

*_not_???   述語の前にnotをつけることで、否定が可能

*_???_all       末尾にallをつけることで、複数の値に対してANDで連結して検索

*_???_any 末尾にanyをつけることで、複数の値に対してORで連結して検索

 

 

= f.attribute_fields do |a|

    = a.attribute_select associations: [:アソシエーションしてるモデルのカラム]

でアソシエーションしてるモデルのカラムをセレクトに選ぶことができる

 

動的に追加されるフォームを作成する方法

/app/helpers/application_helper.rblink_to_add_fieldsメソッドを作成

    module ApplicationHelper

               def link_to_add_fields(name, f, type)

・フォームのあるhtml

= link_to_add_fields “クラス”, f, :カラム

javascriptで動かす