💻
【Rails】検索機能まとめ
コントローラーの作成
ターミナル
rails g controller searches
ルーティング
route.rb
get "search" => "searches#search"
検索バーの作成
form_withヘルパーを使って作成を行います。
_form.html.erb
<% if user_signed_in? %>
<%= form_with url: search_path, method: :get, local: true do |f| %>
<%= f.text_field :word %>
<%= f.select :model, options_for_select({"User" => "user","Book" => "book"}) %>
<%= f.select :search,options_for_select({"完全一致" => "perfect", "前方一致" => "forward", "後方一致" => "backword", "部分一致" => "partial"}) %>
<%= f.submit "検索" %>
<% end %>
<% end %>
- url: search_pathと指定することで、ユーザーが入力した文字列をsearch_controllerのsearchアクションに送ります。データを取得したいのでmethod: :getを指定しています。
- f.text_field :wordとすることで、searchアクション側でparams[:word]を使って、入力した文字列を受け取れるようにします。:mode、:searchも同様です。
- options_for_selectを使って、プルダウンを作成します。表示されるのはUserとBookです。
それぞれ=>でuser、bookが代入されています。 - 3.と同様に検索方法のプルダウンも記述しています。
部分テンプレート
ヘッダーの下に常に表示するよう記述します。
Bootstrapのクラス指定をして中央寄せ、マージンの調整をしています。
application.html.erb
<header>...</header>
.
.
<main>
<div class="d-flex justify-content-center mb-2">
<%= render "searches/form" %>
</div>
<%= yield %>
</main>
.
.
searchesコントローラー
serches_controller.rb
class SearchesController < ApplicationController
before_action :authenticate_user!
def search
@model = params[:model]
@word = params[:word]
@search = params[:search]
if @model == "user"
@records = User.looks(@search, @word)
else
@records = Book.looks(@search, @word)
end
end
end
- フォームで取得した値を変数に代入します。
- if文の条件式を記述します。プルダウンの内容でUserモデルを参照するか、Bookモデルを参照するかが判断されます。
- looksメソッドを使って@search(検索条件)、@word(入力された文字列)から検索内容を取得し、@recordsに代入しています。
検索対象のモデルへの記述
プルダウンの検索方法を実装するための記述を行います。
user.rb
class User < ApplicationRecord
def self.looks(search, word)
if search == 'parfect'
users = User.where("name Like?", "#{word}")
elsif search == 'forward'
users = User.where("name Like?", "#{word}%")
elsif search == 'backward'
users = User.where("name Like?", "%#{word}")
else search == 'partial'
users = User.where("name Like?", "%#{word}%")
end
end
end
1.self.looks(search, word)はlooksメソッドを呼び出すためのレシーバのselfとなっています。selfにはUserが入ります。引数はユーザーがフォームに入力した値を取得します。
2.whereメソッドを使って、条件の検索を行います。今回はUserモデルの中のnameカラムがそれぞれの条件で一致するように実装します。Like句を組み合わせることによって、各検索に適した実装ができます。
book.rb
class Book < ApplicationRecord
def self.looks(search, word)
if search == 'parfect'
books = Book.where("title Like?", "#{word}")
elsif search == 'forward'
books = Book.where("title Like?", "#{word}%")
elsif search == 'backward'
books = Book.where("title Like?", "%#{word}")
else search == 'partial'
books = Book.where("title Like?", "%#{word}%")
end
end
end
Bookモデルも同様に記述します。titleはBookのカラムです。
検索結果の表示
search.html.erb
<% if @model == 'user' %>
<h3>Users search for<%= @word %></h3>
<%= render 'users/index', users: @records %>
<% else @model == 'book' %>
<h3>Books search for<%= @word %></h3>
<%= render 'books/index', books: @records %>
<% end %>
1.if文を用いて検索結果で表示する内容の分岐(プルダウンのUser又はBook)を行っています。
2.renderの変数を変更(@records)することにより、each文で並べた一覧の中の検索結果に合致したデータのみを表示する仕組みになっています。
Discussion