0
0

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]複雑な検索機能の実装

Posted at

はじめに

本記事では、ransackを用いた複雑な検索機能について記述します。
以下の画像のようなものを作成します。

ransack.png

・「名前など」のところには、店名やメニュー名などがキーワードで検索できるようにしました。
・「辛さ(からさ)」では、ActiveHashとしているものとなっています。
・「close」は関係ないので、無視です。

コード

該当箇所記載します。
関係ないところは、省略します。

コントローラー

@q@pなど記載方法は分かれますが、[:q]もあるので、
@qに統一しました。

検索パラメーター(検索する際に入力した内容)のキーを、
:qとしており、queryのイニシャルのことです。

query=質問(by Google先生)

記述し終わったらbinding.pryして、検索してみたら良いと思います。
検索した全ての結果をresultメソッド@foodsとしてインスタンス変数を生成しています。

food_controller.rb
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の書き方いろいろ

明日も頑張ります!!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?