🍎

【Rails】検索機能実装

2023/08/04に公開

はじめに

  • アプリケーション作成済
  • 「searchesコントローラー」を使用して実装
  • 検索時、完全一致、前方一致、後方一致、部分一致を選択できるように実装
  • 検索時、Userモデル/nameカラム、Bookモデル/titleカラムを選択できるように実装
  • 完成イメージ ↓

検索フォーム
altテキスト
検索結果
altテキスト

1.Userモデル、Bookモデルにメソッドを定義

app/models/user.rb
class User < ApplicationRecord
:
:
  #検索方法分岐(nameはusersテーブルのカラム名)
  def self.looks(search, word)
    if search == "perfect_match"    #完全一致
      @user = User.where("name LIKE?", "#{word}")
    elsif search == "forward_match"  #前方一致
      @user = User.where("name LIKE?", "#{word}%")
    elsif search == "backward_math"  #後方一致
      @user = User.where("name LIKE?", "%#{word}")
    elsif search == "partial_match"  #部分一致
      @user = User.where("name LIKE?", "%#{word}%")
    else
      @user = User.all
    end
  end
:
app/models/book.rb
class Book < ApplicationRecord
:
:
  #検索方法分岐(titleはbooksテーブルのカラム名)
  def self.looks(search, word)
    if search == "perfect_match"    #完全一致
      @book = Book.where("title LIKE?", "#{word}")
    elsif search == "forward_match"  #前方一致
      @book = Book.where("title LIKE?", "#{word}%")
    elsif search == "backward_math"  #後方一致
      @book = Book.where("title LIKE?", "%#{word}")
    elsif search == "partial_match"  #部分一致
      @book = Book.where("title LIKE?", "%#{word}%")
    else
      @book = Book.all
    end
  end
:

2.ルーティング設定

config/routes.rb
Rails.application.routes.draw do
:   
  get "search" => "searches#search"
:
end
ターミナル
$ rails routes

ルーティングを確認!

ターミナル
search GET    /search(.:format)    searches#search
  • 検索をかけると、searchesコントローラー/searchアクションが動く

3.コントローラー作成

ターミナル
$ rails g controller searches

ルーティングで設定したsearchアクションを記述

app/controllers/searches_controller.rb
class SearchesController < ApplicationController
  
  def search
  end
  
end

4.アクションを実装

app/controllers/searches_controller.rb
class SearchesController < ApplicationController
  
  def search
    @range = params[:range]
    @word = params[:word]
    
    if @range == "User"
      @users = User.looks(params[:search], params[:word])
    else
      @books = Book.looks(params[:search], params[:word])
    end
  end
  
end

5.検索フォーム作成

app/views/layoutsに部分テンプレート「_search.html.erb」を作成

app/views/layouts_search.html.erb
<% if user_signed_in? %>
<div class="search_form">
  <%= form_with url: search_path, local: true, method: :get do |f| %>
    <%= f.text_field :word %>
    <%= f.select :range, options_for_select([['User'],['Book']]) %>
    <%= f.select :search, options_for_select([["完全一致","perfect_match"],["前方一致","forward_match"],["後方一致","backward_match"],["部分一致","partial_match"]]) %>
    <%= f.submit "検索", class: "btn-sm btn-primary" %>
  <% end %>
</div>
<% end %>
app/views/layouts/_header.html.erb
<!--検索窓-->
<div class="row justify-content-center">
  <%= render "layouts/search" %>
</div>

検索フォームが表示されるようになりました!
altテキスト

6.検索結果一覧ページ作成

app/views/searchesに「search.html.erb」を作成
altテキスト

app/views/searches/search.html.erb
<table class="table table-hover table-inverse">
  <!--検索対象モデルがUser-->
  <% if @range == "User" %>
  <h2>Users search for "<%= @word %>"</h2>
    <thead>
      <tr>
        <th>Image</th>
        <th>name</th>
        <th colspan="3"></th>
      </tr>
    </thead>
    <tbody>
      <% @users.each do |user| %>
      <tr>
        <td><%= image_tag user.get_profile_image(50, 50) %></td>
        <td><%= user.name %></td>
      </tr>
      <% end %>
    </tbody>
  <% else %>
  <!--検索対象モデルがBook-->
    <thead>
      <tr>
        <th></th>
        <th>Title</th>
        <th>Opinion</th>
      </tr>
    </thead>
    <tbody>
      <h2>Books search for "<%= @word %>"</h2>
      <% @books.each do |book| %>
        <tr>
          <td>
            <%= link_to user_path(book.user) do %>
              <%= image_tag book.user.get_profile_image(50, 50) %>
            <% end %>
          </td>
          <td><%= link_to book.title, book_path(book.id) %></td>
          <td><%= book.body %></td>
        </tr>
      <% end %>
    </tbody>
  <% end %>
</table>

User(nameカラム)検索結果!
altテキスト
Book(titleカラム)検索結果!
altテキスト


以上で検索機能の実装が完了しました!

Discussion