検索機能の実装
検索機能の実装
今回も以前に作成したBookers2のアプリケーションに検索機能を実装していく。
今回はGemを使用しない方法で実装していく。
実装する機能
コントローラ
searchesコントローラの作成
searchアクション追加(用途:検索を行う)
ビュー
ログインしている場合に限り、ヘッダーに検索窓・検索ボタンを設置すること
検索結果表示画面を作成し、検索結果を表示すること
検索対象(ユーザーか投稿か)の選択かをプルダウンメニューで選択できること
ルーティング
検索ボタン実行時、searchesコントローラのsearchアクションが実行されるように定義。
config/routes.rb
: get "search", to: "searches#search" :
コントローラ
コントローラの作成
searchesコントローラを作成していく。
$ rails g controller searches
アクションの記述
searchesコントローラにsearchアクションを記述していく。
app/controllers/searches_controller.rb
class SearchesController < ApplicationController def search @model = params[:model] @content = params[:content] @method = params[:method] if @model == 'user' @records = User.search_for(@content, @method) else @records = Book.search_for(@content, @method) end end end
- 下記のコードにて検索フォームからの情報を受け取っています。
@model : 検索モデル(User、Bookから選択)
@content : 検索ワード(ユーザーが自由記述)
@method : 検索方法(前方一致、後方一致、部分一致、完全一致から選択)
if文で、検索モデルがUserの場合とBookの場合で、条件分岐させて、
search_forメソッドの引数に検索ワードと検索方法を渡して、検索を実行し、@recordsに代入しています。
現状では、search_forメソッドの定義をしていないため、モデルにメソッドの定義をしていきます。
モデル
モデルにメソッドの定義
app/models/users.rb
: def self.search_for(content, method) if method == 'perfect' User.where(name: content) elsif method == 'forward' User.where('name LIKE ?', content + '%') elsif method == 'backward' User.where('name LIKE ?', '%' + content) else User.where('name LIKE ?', '%' + content + '%') end end :
app/models/books.rb
: def self.search_for(content, method) if method == 'perfect' Book.where(title: content) elsif method == 'forward' Book.where('title LIKE ?', content+'%') elsif method == 'backward' Book.where('title LIKE ?', '%'+content) else Book.where('title LIKE ?', '%'+content+'%') end end :
selfを使用し、クラスメソッドsearch_forを作成する。
whereで検索した結果を全て取得する。
Userモデルのname、Bookモデルのtitleは検索するモデルのカラム名である。
Userであれば、nameカラムを検索し、条件に合う結果を取得する。
ビュー
ヘッダーに検索窓・検索ボタンの作成
/views/searchesフォルダに部分テンプレート_form.html.erbを作成し、記述していく。
app/views/searches/_form.html.erb
<% if user_signed_in? %> <%= form_with url: search_path, method: :get, local: true do |f| %> <%= f.text_field :content %> <%= f.select :model, options_for_select({"User" => "user", "Book" => "book" }) %> <%= f.select :method, options_for_select({ "完全一致" => "perfect", "前方一致" => "forward", "後方一致" => "backward", "部分一致" => "partial"}) %> <%= f.submit '検索' %> <% end %> <% end %>
ヘッダーの部分テンプレートに検索窓・ボタンの追加
app/views/layouts/_header.html.erb
: <div> <%= render 'searches/form' %> </div> :
検索結果の表示ビュー作成
/views/searchesフォルダにsearch.html.erbを作成し、記述していく。
app/views/searches/search.html.erb
<% if @model == 'user' %> <h3>Users search for "<%= @content %>"</h3> <%= render 'users/index', users: @records %> <% elsif @model == 'book' %> <h3>Books search for "<%= @content %>"</h3> <%= render 'books/index', books: @records %> <% end %>
以上で、検索機能の実装が完了。