★【Rails】検索機能(collectionとmember)
今回は検索したテキストを含む投稿のみを
表示させられる機能を追加する方法を説明したいと思います。
トップページにフォームを表示させたいので、
index.html.erbにフォームを追加します。
<%= form_with ( url : search_posts_path , local : true , method : : get , class : "search-form" ) do | form | %>
<%= form. text_field : keyword, placeholder: "投稿を検索する", class: "search-input" %>
<%= form . submit "検索" , class : "search-btn" %>
<% end %>
これで入力フォームと検索ボタンを配置できました。
まだルーティングができていないので、
searchアクションのルーティングを行いましょう。
こちら7つのアクション以外のアクションですね。
ここでルーティングを設定したい際に使える
collectionとmemberを学習します。
これらを使用することによって生成されるルーティングのURLと
実行されるコントローラーを任意にカスタムできます。
この2つの違いは : id が紐づくかどうかです。
collectionは : id 無し
memberは : id 有り
となります。
では実際にルーティングを行います。
今回もポストを関連づける必要があるのでネストを利用しましょう。
また、 : id を使用して特定のページにいく必要はないので、
collectionを使います。
collection do
get ' search '
end
これでルーティングの完了です。
では次にメソッドの定義をしましょう。
メソッド名はsearchメソッドとします。
ビジネスロックという「データに対する処理」に関してはモデルに記載します。
具体的には「データをどのように処理するか」「どのデータを取得するのか」、
「どんな手順で処理していくのか」などを指します。
ということでsearchメソッドをPostモデルに定義しましょう。
そこで、検索したキーワードが含まれている投稿を取得するためには、
whereメソッドとLIKE句を使用します。
whereメソッドはモデルが使用できる
ActiveRecordメソッドの一つです。
モデル. where(条件)と引数に条件を指定すると、
一致したレコードのインスタンスを配列で取得できます。
なので条件には「検索対象となるカラム」を必ず含めましょう。
LIKE句は曖昧な文字列を検索するときに使用し、
whereメソッドと一緒に使用します。
def self.search ( search )
if search ! = " "
Post . where ( ' text LIKE (?) ' , "%#{ search}%" )
else
Post . all
end
end
引数のsearchにはフォームから送信されたパラメーターが入ります。
if search ! = " "というのは「フォームが空欄でなければ」
処理を実行するという意味ですね。
そうでなければPost . allで全てのデータが取得されます。
' text LIKE (?) ' , "%#{ search}%"
そしてここですね。
#{ search}が含まれているタイトルを表しています。
ここでの%は任意の文字列を指します。
textの部分はtitleなどに変更することができます。
ではコントローラーにアクションを定義しましょう、
def search
@posts = Post . search ( params [ : keyword ] )
end
ここでPostモデルに書いたsearchメソッドを呼び出してます。
またsearchメソッドの引数にparams [ : keyword ] を記載して
検索結果を渡しています。
これであとはビューを作成して完成です!