#はじめに
今回は投稿されたマイクロポストを入力された文字からあいまい検索する機能を追加します。
###作るもの
railsのform_withヘルパーを利用した投稿の検索機能。(題材は自分のポートフォリオ)
###対象読者
railsチュートリアル終了後等に何か機能を追加したい人等。
#作成の流れ
1.対応するビューの作成
2.コントローラーの編集
#1.対応するビューの作成
今回は検索フォームをroot_path上に設けます。(自分のポートフォリオがマイクロポストの一覧をroot_path(static_pages/home)に設けているため)
<%= form_with( url: root_path, class: 'search_form', method: :get, local:true) do |f| %>
<%= f.text_field :search,class: 'field',value: params[:search]\
placeholder: "スレ・コメント検索"%>
<%= f.submit '検索', class: "btn" %>
form_withを利用して検索フォームを作ります。各値は
url:root_path検索後に表示するページ
method:get(httpメゾット。今回はページの取得なのでget)
local:true(ajax処理(非同期通信)を無効にする。デフォルトではajaxで処理する。)
text_field: search 入力フォームになります。
value: params[:search]と値を設定しておくことで検索後も値を保持します。(URLのクエリから取得。)
あとはget動作を開始させるsubmitを配置します。
検索ボタンを押せばurlのページを表示しようとするので検索の処理は対応するコントローラーのアクション内に書きます。
#2.コントローラーの編集
コントローラーで送られた値を処理しますが、コントローラー内に処理を全て書くとごちゃごちゃしてしまいますのでDBとやりとりをする箇所はmodel側で記述します。
@microposts = params[:search].present? ? Micropost.micropost_serach(params[:search]) : Micropost.all
@microposts = params[:search].present?で値がsearchに値が入っているか(検索ボタンが押されているか)
値が入っていればmicropost_serachを動作させます。(中身は後ほどmodelに記載)値が入ってなければ、Micropost.allで全てのマイクロポストを表示させます。(そのあとは適宜ページネーション等に渡してください。)
ではmicropost_serachの中身です。
def self.micropost_serach(search)
Micropost.where(['title LIKE ?', "%#{search}%"])
end
whereメゾットとLIKE旬でマイクロポストの中からあいまい検索をします。
モデル名.where([カラム名前 LIKE ?, "検索したい文字列"])
検索したい文字列の両サイドにある「%」は任意の複数の文字列を表しています。
上記のは一つしかカラムを指定していませんが複数指定することもできます。
def self.micropost_serach(search)
Micropost.where(['title LIKE ? OR content LIKE ?', "%#{search}%", "%#{search}%"])
end
複数のカラムを指定する場合はカラム数に応じてORやANDで繋ぎ、検索したい文字列を増やしてあげると検索できます。
今回はさらに、マイクロポストにコメントされた文章も含めて検索してみます。
コメント機能についてこちら
https://qiita.com/E6YOteYPzmFGfOD/items/ef776d34908872ea19f7
def self.micropost_serach(search)
Micropost.includes(:comments).where(['microposts.title LIKE ? OR microposts.content LIKE ? OR comments.content LIKE ?',
"%#{search}%", "%#{search}%", "%#{search}%"]).references(:comments)
end
これでコメント内も合わせて検索できるようになりました
#終わりに
最後までお読みいただきありがとうございました。検索文はいろいろパターンがあるので今後も新しい物を書いたときには記事にしてみようと思います。
ありがとうございました。