概要
検索機能を実装する方法をまとめました。
例として、写真投稿アプリに基本的な検索機能を実装する方法を紹介します。
初学者なので、間違いがあればご指摘いただきたいです。
参照
以下のページを参照しました。ありがとうございました。
Railsで検索機能を実装する方法を現役エンジニアが解説【初心者向け】
完成イメージ
環境
- macOS Catalina 10.15.7
- ruby 2.6.5
- Rails 6.0.3.4
実装の流れ
- ルーティングを追加
- コントローラーにsearchメソッドを作成
- 検索フォームを作成
- 検索結果表示画面を作成
今回のコード
1. ルーティングを追加
routes.rb
resources :photos do
resources :comments, only: :create
collection do
get 'search'
end
end
- photosコントローラーにsearchアクションを追加します。
- collectionとすることで:idを含まないルーティングになります。
ちなみに、memberとすると:idを含むルーティングになります。
参照:https://qiita.com/k152744/items/141345e34fc0095217fe
2. コントローラーにsearchメソッドを作成
photos_controller.rb
def search
if params[:keyword].present?
@photos = Photo.where('caption LIKE ?', "%#{params[:keyword]}%")
@keyword = params[:keyword]
else
@photos = Photo.all
end
end
- 検索ボタンをクリックするとsearchアクションが呼び出され、入力した検索ワードをparams[:keyword]で取得できます。:keywordでなくとも好きなキー名をつけることができますが、今回は:keywordとしました。
- 今回は写真のキャプションで検索するため、Photo.where('caption LIKE ?', "%#{params[:keyword]}%")としました。これで、入力した検索ワードがキャプション内に含まれる写真をすべて取得できます。whereメソッドの使い方については、以下をご参照ください。https://techacademy.jp/magazine/22330
- 何も入力せずに検索ボタンをクリックした場合は、Photo.allですべての写真を取得することとしました。
- 入力した検索ワードを取得して検索結果表示画面で使用するため、@keyword = params[:keyword]としました。
3. 検索フォームを作成
index.html.erb
# クラス名などは省略してあります
<%= form_with url: search_photos_path, local: true, method: :get do |form| %>
<%= form.text_field :keyword %>
<%= form.submit "検索" %>
<% end %>
- form.text_field :keywordとすることで、検索ボタンをクリックした後、:keywordキーに、入力した検索ワードが値として設定されます。コントローラーのsearchメソッドでparams[:keyword]と設定すると、その値を取得することができます。
4. 検索結果表示画面を作成
search.html.erb
## クラス名などは省略してあります
<h2>検索結果 "<%= @keyword %>"</h2>
<ul>
<% @photos.each do |photo| %>
<li>
<%= link_to photo_path(photo.id) do %>
<%= image_tag photo.image.variant(gravity: :center, resize:"640x640^", crop:"640x640+0+0"), if photo.image.attached? %>
<% end %>
</li>
<% end %>
</ul>
- 上記のとおり、コントローラーのsearchメソッドで、検索ワードが含まれる写真を@photosに格納しました。@photos.each do |photo|で、それらひとつひとつの写真を取り出し、画面に表示させます。
- <%= @keyword %>で、入力した検索ワードも表示させました。
おわりに
以上が、今回行った基本的な検索機能実装の方法です。
ハッシュタグ検索など、より高度な検索も今後挑戦してみたいですね。