検索機能の実装

検索機能の実装

今回も以前に作成した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 %>

以上で、検索機能の実装が完了。