検索機能の追加
実装機能
・searchesコントローラ(searchアクション)
・ログイン中は常に検索ボックスを表示
・検索対象は User / Book の2択をプルダウンで選択
・検索方法は完全一致、部分一致、前方一致、後方一致の4つをプルダウンで選択
・検索結果一覧のビュー
前提
・deviseを使用
・userモデル / bookモデルを作成済み
step1 ルーティングの作成
get "search" => "searches#search"
step2 コントローラーの作成
$ rails g controller searches
searchesコントローラを作成する。
step3 ビューの作成(検索ボックス)
<% if user_signed_in? %>
<%= form_with url: search_path, method: :get, local: true do |f| %>
<%= f.text_field :word %>
<%= f.select :data, options_for_select([['User'], ['Book']]) %>
<%= f.select :method, options_for_select([["完全一致", "perfect"], ["前方一致", "forward"], ["後方一致", "backward"], ["部分一致", "partial"]]) %>
<%= f.submit "検索", class: "btn btn-secondary" %>
<% end %>
<% end %>
・検索ボックスに入力する文字列 → word
検索対象(User/Book) → data
検索方法(完全一致/前方一致/後方一致/部分一致) → method
として、入力内容をアクションに送付します。
・options_for_selectは、選択肢を生成します。
選択肢は引数の配列に入れます。
[['User'], ['Book']] この場合、選択肢のテキストと値は同じものになります。
[["完全一致", "perfect"], ["前方一致", "forward"], ...]
この場合、 配列の中の配列の1つ目が選択肢のテキスト、2つ目が値になります。
*form_with メソッド内に、local: true を記述することで、確実に同期通信を行うことができる。
上記コードをレンダリングします。
<%= render 'searches/search_box' %>
step4 アクションの作成
before_action :authenticate_user!
def search
@data = params[:data]
@word = params[:word]
@method = params[:method]
if @data == "User"
@users = User.look_for(@word, @method)
else #@data == "Book"
@books = Book.look_for(@word, @method)
end
end
・下部分のコードで、
@data には、選択した検索対象(User/Book)
@word には、検索ボックスに入力した値
@method には、選択した検索方法(完全一致/前方一致/後方一致/部分一致)を代入します。
@data = params[:data]
@word = params[:word]
@method = params[:method]
・検索対象が Userなら、 @usersに、
検索対象が Bookなら、 @booksに、検索ボックスに入力した情報を代入します。
・look_for(word, method)は、これから定義します。
step5 look_for(条件分岐)の作成
def self.look_for(word, method)
if method == "perfect"
@user = User.where("name LIKE ?", "#{word}")
elsif method == "forward"
@user = User.where("name LIKE ?", "#{word}%")
elsif method == "backward"
@user = User.where("name LIKE ?", "%#{word}")
elsif method == "partial"
@user = User.where("name LIKE ?", "%#{word}%")
end
end
def self.look_for(word, method)
if method == "perfect"
@book = Book.where("title LIKE ?", "#{word}")
elsif method == "forward"
@book = Book.where("title LIKE ?", "#{word}%")
elsif method == "backward"
@book = Book.where("title LIKE ?", "%#{word}")
elsif method == "partial"
@book = Book.where("title LIKE ?", "%#{word}%")
end
end
以下の部分は
if method == "perfect"
@book = Book.where("title LIKE ?", "#{word}")
method(検索方法)が、"perfect"なら、
Bookモデルのデータの中で、
titleが word(検索ボックスに入力した文字列)と同じもの
を全部 @bookに代入する
という意味になります。
("title LIKE ?", "#{word}")
("カラム名 LIKE ?", "検索したい文字列")
という感じです。
#{word}の前後についていたり、ついていなかったりする % は、
正規表現の書き方です。
step6 ビューの作成(検索結果一覧)
searchアクションで代入した、
@users または @books を用いて、一覧画面を作成します。
<h2>Results</h2>
<table class="table table-hover table-inverse">
<% if @data == "User" %>
<tbody>
<% @users.each do |user| %>
<tr>
<td><%= image_tag user.get_profile_image, size: "50x50" %></td>
<td><%= user.name %></td>
</tr>
<% end %>
</tbody>
<% else %>
<tbody>
<% @books.each do |book| %>
<tr>
<td><%= image_tag book.user.get_profile_image, size: "50x50" %></td>
<td><%= book.title %></td>
<td><%= book.body %></td>
</tr>
<% end %>
</tbody>
<% end %>
</table>
参照
Discussion