本記事は 駆け出しエンジニアの第一歩!AdventCalendar2020 9日目の記事です。
作りたいもの
下図のように一つの検索バーで複数のテーブルのデータを取得する機能を実装します。
下図ではMagicテーブル、Productテーブル、Userテーブルの3つのテーブルに検索をかけて、それぞれのテーブルで検索条件にヒットするデータを取得し、タブで表示を切り替えています。
やることまとめ
1.検索機能のルーティングを設定する。
2.ビューに検索バーを実装する。
3.コントローラに検索機能を実装する。
1.検索機能のルーティングを設定する
検索ボタンがクリックされた時に、どのコントローラのどのアクションを呼び出すかをroute.rbに記載します。
下記例では、homes_controller.rbのsearchアクションを呼び出すようにしています。
# 検索機能実施
get '/search' => 'homes#search', as: 'search'
2.ビューに検索バーを実装する
次に検索フォームを用意します。
私の場合はヘッダーに検索フォームを表示させたかったので、_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つのテーブルそれぞれで検索をかけています。
# 検索機能
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}%")
という式になっています。
上記例は部分一致検索となっております。
おわりに
検索結果画面も載せられればと思ったのですが、かなり複雑になっていたので今回は割愛させてもらいました…汗