💻
【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