0
2

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.

【Rails】ransackを使わずに1つの検索バーで複数テーブルのデータを検索する

Posted at

本記事は 駆け出しエンジニアの第一歩!AdventCalendar2020 9日目の記事です。

作りたいもの

下図のように一つの検索バーで複数のテーブルのデータを取得する機能を実装します。
下図ではMagicテーブル、Productテーブル、Userテーブルの3つのテーブルに検索をかけて、それぞれのテーブルで検索条件にヒットするデータを取得し、タブで表示を切り替えています。

image.png

image.png

やることまとめ

1.検索機能のルーティングを設定する。
2.ビューに検索バーを実装する。
3.コントローラに検索機能を実装する。

1.検索機能のルーティングを設定する

検索ボタンがクリックされた時に、どのコントローラのどのアクションを呼び出すかをroute.rbに記載します。
下記例では、homes_controller.rbのsearchアクションを呼び出すようにしています。

route.rb

# 検索機能実施
get '/search' => 'homes#search', as: 'search'

2.ビューに検索バーを実装する

次に検索フォームを用意します。
私の場合はヘッダーに検索フォームを表示させたかったので、_header.html.erbに下記コードを実装しました。

_header.html.erb

<%= form_with url: search_path, method: :get, local: true do |f| %>

  <!-- 検索フォーム -->
  <%= f.text_field :content, :placeholder => "マジック動画タイトル、商品名、ユーザー名で検索" %>

  <!-- 検索ボタン -->
  <%= f.button :type => "submit" do %>
    <i class='fas fa-search'></i>
  <% end %>

<% end %>

解説


<%= form_with url: search_path, method: :get, local: true do |f| %>

form_withヘルパーを用いて、検索条件をコントローラまで渡してあげます。
ここでは、URLに/searchを指定し、getメソッドでアクセスするという内容を書いています。


<!-- 検索フォーム -->
<%= f.text_field :content, :placeholder => "マジック動画タイトル、商品名、ユーザー名で検索" %>

f.text_fieldは検索フォームの検索ワードを入力するinput要素を指しています。
入力した検索ワードは:contentに格納されます。(後ほどコントローラで開封します。)


<!-- 検索ボタン -->
<%= f.button :type => "submit" do %>
  <i class='fas fa-search'></i>
<% end %>

form_withヘルパーではsubmitボタンをクリックすると、指定のルーティング先へ遷移するようになっています。
ここではそのsubmitボタンを虫眼鏡アイコンにする処理を書いています。

3.コントローラに検索機能を実装する

コントローラでは、form_withヘルパーより送られてきた検索ワード(:content)を受け取り、それを基に3つのテーブルそれぞれで検索をかけています。

homes_controller.rb

# 検索機能
def search
  # 検索ワード
  content = params['content']
  # 投稿検索結果
  @magics = partical_magic(content)
  # 商品検索結果
  @products = partical_product(content)
  # ユーザー検索
  @users = partical_user(content)
end

private

# 投稿検索
def partical_magic(content)
  Magic.where('title LIKE ?', "%#{content}%")
end

# 商品検索
def partical_product(content)
  Product.where('name LIKE ?', "%#{content}%")
end

# ユーザー検索
def partical_user(content)
  User.where('display_name LIKE ?', "%#{content}%")
end

解説


# 検索ワード
content = params['content']

form_withヘルパーから送られてきたパラメータ:contentの中身、すなわち検索ワードをcontent変数に格納しています。


# 投稿検索結果
@magics = partical_magic(content)
# 商品検索結果
@products = partical_product(content)
# ユーザー検索
@users = partical_user(content)

検索結果用のインスタンス変数を3つ用意し、それぞれに検索結果を格納しています。
それぞれの式の右辺では検索を行うメソッドに先ほど格納したcontent変数を引数として渡しています。


# 投稿検索
def partical_magic(content)
  Magic.where('title LIKE ?', "%#{content}%")
end

# 商品検索
def partical_product(content)
  Product.where('name LIKE ?', "%#{content}%")
end

# ユーザー検索
def partical_user(content)
  User.where('display_name LIKE ?', "%#{content}%")
end

それぞれのテーブルに対して検索を行い、データを返すメソッドです。
モデル名.where('[検索対象カラム] LIKE ?', "%#{content}%")
という式になっています。
上記例は部分一致検索となっております。

おわりに

検索結果画面も載せられればと思ったのですが、かなり複雑になっていたので今回は割愛させてもらいました…汗

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?