経緯
現在絶賛作成中のポートフォリオで、フリマアプリのラクマの仕上げに検索機能をの実装したいと思い作成。さほど難しくはなかったけれども、色々記載しておこうと思います。
環境
ruby 2.6.5
Rails 6.0.3.2
haml使用
イメージ図
手順
1、ルーティングの設定
2、検索フォームを作成
3、モデルに定義
4、コントローラーに設定
5、ビューの作成
の5つの手順になります。
簡単なので、サックと出来ると思います。
ルーティングの設定
今回は、7つの基本アクション以外のアクションを定義します。
7つの基本アクションとは、index
new
create
等のアクションの事ですね。
先ずは、コードから
resources :items do
collection do
get 'search'
end
end
説明ですが、
今回は先程言った通り7つの基本アクション以外で定義します。要は新しいアクションを作るみたいなイメージです。
その為のコードが、collection ~ end
の所です。
get の横のsearch
が新しいアクション名です。
そして、collection
ですが、ここはURLの指定先にidの必要の可否で変わります。
idの可とは、showアクションのような個々に登録されている商品の詳細ページなどに見にいく時にふられるものです(まぁ、ふられると言うと言葉のニュアンス的に違うのですが・・・)
なので、idなしで有ればcollection
idありで有ればmember となります。
今回は、特定のページにいく必要がないため、collection
を使用してルーティングを設定してます。
検索フォームを作成
先ずは、コードから
= form_with(url: search_items_path, local: true, method: :get, class: "search-form") do |f|
= f.text_field :keyword, placeholder: "検索する", class: "search-input"
%label{for: "search-icon", class: "search-label"}
%i.fas.fa-search
.search-icon
= f.submit "検索", class: "search-btn", id: "search-icon"
必要そうな所だけ説明します。
先ずは、urlの設定部分ですが、先程設定したsearchのルーティングで設定されるplefixを書きます。plefixをパスとして書く時は文字の最後に_pathをつけるような書き方をします。
調べ方は、ご存知だと思いますが、
ターミナルで rails routes
です。
次に、まぁこれは無理に行う必要はないですが、上記の画像のように、ムシメガネ🔍みたいなアイコンとsubmit(送信ボタン)の紐付けについてです。
つまり、ムシメガネ🔍みたいなアイコンを押したら送信ボタンが押されるように設定していると言う事です。
やり方は、label:for と id で紐付けます。
上記のコードで言うと、
これと %label{for: "search-icon", class: "search-label"}
これで = f.submit "検索", class: "search-btn", id: "search-icon"
です。
search-icon
って言う同じ名前がありますよね。これで紐付けされています。
そして、今回は検索フォームにf.text_field :keyword
と記述したので、このフォームに入力した値はコントローラーでparams[:keyword]
と書くことで取得する事ができます。
モデルに定義
ここも、コードから
def self.search(search)
return Item.all unless search
Item.where('name LIKE(?)', "%#{search}%")
end
言い忘れましたが、今回はitemって言う名前でモデル等を作ってます。
説明します。
検索したキーワードが含まれている投稿を取得するために、whereメソッドとLIKE句を利用します。
whereメソッドは、モデル名.where('検索対象となるカラムを含む条件式')とする事でテーブル内の「条件に一致したレコードのインスタンス」を配列の形で取得できます。
LIKE句は、曖昧(あいまい)な文字列の検索をするときに使用するもので、whereメソッドと一緒に使います。
詳細は、省きますが今回は、searchが含まれるnameカラムのデータを検索するものです。
詳しく知りたい方は、下記のリンク先が分かりやすいと思います。
【SQL】LIKE句の基本的な使い方~複数検索する場合の方法まで解説
そもそも、searchって何?っと思われた方の向けに説明します。
要は引数の話です。
引数のsearch(1行目の(search)
)は、検索フォームから送信されたパラメーターが入ります。イメージしやすく言うと、検索フォームに みかん と入力して送信ボタンを押すとこの引数に みかん が入ると言う事ですね。
後は、文法の話です。
この引数にみかんというデータが入れば定義の中のsearchもみかんになるって訳です。つまり、このまま、みかんネタで言えば、itemテーブルのnameカラムにみかんと言う文字が入っているものを検索するって言う事です。
なので、言ってしまえば、1行目の(search)
はどんな単語でも良いって事ですね。
次に、return Item.all unless search
ですが、これは読んで字のごとくですが、
search(さっきので言えばみかん)と言う文字がなかったら他全てを出力すると言う意味です。
そして、最後に1行目のself.search
の説明です。
現時点だと、.search
というメソッドは使うことができません(この後コントローラーで定義するのに使います)
が、モデルで設定することにより、コントローラーで使用することができるようになります。そして、モデルの中でメソッドを定義する際には、メソッド名の頭にself.
を付けると事で、コントローラーで使えるクラスメソッドになります。
以上で、モデルに定義は終了です。
コントローラーに設定
はたまた、ここもコードから
def search
@items = Item.search(params[:keyword])
end
@items = Item.search(params[:keyword])
のコードは、
上記で述べてきた、今迄の説明で事足りるかと思うので省略します。
ビューの作成
検索結果画面のビューの作成ですが、
ここは、search.html.haml
と言うファイルを作成して、
eachメソッドを使って出力すればオッケーかと思います。
.contents__box
- @items.each do |item|
ここより下は今自分が作っているものに照らし合わせて作成お願いします。
これで、全ての実装が完了です!
実装出来なかったなどの不備が有ればご連絡ください!
ありがとうございました。