はじめに
本記事では、ransack
を用いた複雑な検索機能について記述します。
以下の画像のようなものを作成します。
・「名前など」のところには、店名やメニュー名などがキーワードで検索できるようにしました。
・「辛さ(からさ)」では、ActiveHashとしているものとなっています。
・「close」は関係ないので、無視です。
コード
該当箇所記載します。
関係ないところは、省略
します。
コントローラー
@q
や@p
など記載方法は分かれますが、[:q]
もあるので、
@q
に統一しました。
検索パラメーター
(検索する際に入力した内容)のキーを、
:q
としており、queryのイニシャル
のことです。
query=質問(by Google先生)
記述し終わったらbinding.pry
して、検索してみたら良いと思います。
検索した全ての結果をresultメソッド
で@foods
としてインスタンス変数を生成しています。
class FoodsController < ApplicationController
def index
(省略)
@q = Food.ransack(params[:q])
end
def search
@q = Food.ransack(params[:q])
@foods = @q.result
end
(省略)
ビュー
search.html.erb
検索結果をeachメソッドで、すべて表示しています。
また、条件分岐で、検索結果が該当なしの場合は、
デカデカと「Sorry」しました。
ここは特にいうことはありません。
<div class="main">
<div class="food-contents">
<h2 class="food-contents-title">検索結果</h2>
<% if @foods.present? %>
<ul class="food-lists">
<% @foods.each do |food| %>
<li class="list">
<div class="food-img-content">
<h2 class="food-post-user">
<%= link_to user_path(food.user_id) do %>
<% if food.user.icon.present? %>
<%= image_tag food.user.icon, class: "icon-img" %>
<% else %>
<i class="fas fa-user-circle"></i>
<% end %>
<%= food.user.nickname %>
<% end %>
</h2>
<%= link_to food_path(food) do %>
<%= image_tag food.image, class: "food-img" if food.image.attached? %>
<div class="food-img-info">
<h2 class="shop-name">
<%= food.shop_name%>
</h2>
<h2 class="food-name">
<%= food.food_name%>
</h2>
</div>
<% end %>
</div>
</li>
<% end %>
</ul>
<% else %>
<div class="non">
<h2 class="non-title">SORRY...</h2>
</div>
<% end %>
</div>
</div>
フォームのerbファイル
ここは何時間も悩みました。
複数のカラムの1つのフォームで検索ができるようにするには、
_or_
をつける必要があります。
これをつけずに、カラム間に:
とかつけると、
ArgumentError
がでると思います。
メソッドの引数が正しくない時や数が多かったり、少ない時に発生するエラーですね。
collection_selectにおける引数について
第一引数(メソッド名)
・カラム名やname属性やid属性を決定
第二引数(オブジェクト)
・配列データを指定する
・ActiveHash
なので、ここをインスタンス変数とかにすると、エラー地獄になります。(震え)
今回では、SpicyLevel.all
です。
第三引数(value)
表示する際に参照するDBのカラム名
第四引数(name)
実際に表示されるカラム名
オプションinclude_blank
何も選択していない時に表示される内容
(今回では「--」にしてます。)
それらを踏まえ、以下コードです。
私はここでform_with
とサヨナラすることになりました。
いきなりransackで検索機能実装している強者は、出会ってもないと思いますが。
<%# form_with、さよなら %>
<%= search_form_for @q, url: search_foods_path, class: "food-search", id:"pull-down" do |f| %>
<%= f.label :shop_name_or_shop_name_kana_or_food_name_or_station_cont, '名前など' %>
<%= f.text_field :shop_name_or_shop_name_kana_or_food_name_or_station_cont, placeholder: "TYPE A KEYWORD" %>
<%= f.label :spicy_level_id_eq, '辛さ' %>
<%= f.collection_select :spicy_level_id_eq, SpicyLevel.all, :id, :name, include_blank: '--' %>
<%= f.submit "SEARCH" %>
<% end %>
以上です。
いかがでしょうか。
終わりに
なかなか手強く、これを実装するのに8時間かかりました。😇
しかし、実装できたときはやはり気持ちいいですねえ。
情報化社会の世の中、検索が不十分なアプリケーションは私は微妙ではないかなと思いましたので、
めげずに頑張りました。
また、
他のサイトを見るとseedファイルを使っている方がおりましたが、
私は、使いませんでした。
まあ、いいか。
以下今回の参考サイトです。
Pikawakaというサイトは本当にわかりやすくてすごいなと思います。
Railsでrake db:seedをやり直す
【Rails】 ransackを使って検索機能がついたアプリを作ろう!
gemのransackで複数カラムを検索対象にする方法
【Rails】ransackの使い方をざっくりまとめてみた
【Rails】検索機能の実装手順
[rails]ransackを使用して検索機能
[Rails]ransackを利用した色々な検索フォーム作成方法まとめ
Rails db:seed二重登録解除
railsのseedの書き方いろいろ
明日も頑張ります!!