1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Ruby on Rails】検索機能追加

Last updated at Posted at 2022-07-04

開発環境

Rails 6.1.4
ruby 2.6.3

前提条件

  • devise導入
  • Bootstrap導入
  • Userモデル、Bookモデル実装済み
  • ユーザーの一覧表示と投稿一覧は部分テンプレートで作成済み

目次

  • コントローラー作成
  • ルーティング
  • モデル定義
  • View作成

①コントローラー作成

まずは検索機能のコントローラーを作成します。
同時にコントローラーアクションも作成します。

ターミナル
$ rails g controller searches search

searchesコントローラーのsearchアクションを定義します

searches.contoroller.rb
class SearchesController < ApplicationController
  before_action :authenticate_user!

  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
  • 下記コードにて検索フォームからの情報を受け取っています。
     検索モデル→params[:range]
     検索方法 →params[:search]
     検索ワード→params[:word]

  • if文を使い、検索モデルUserorBookで条件分岐させます。

  • looksメソッドを使い、検索内容を取得し、変数に代入します。
     検索方法params[:search]と、検索ワードparams[:word]を参照してデータを検索し、
     1:インスタンス変数@usersにUserモデル内での検索結果を代入
     2:インスタンス変数@booksにBookモデル内での検索結果を代入

また、インスタンス変数@wordに検索ワードを代入するため定義します。
(検索結果の画面で使用します)

②ルーティング

ルーティングを定義します。
searches controller作成と同時にルーティングも作成されているはずなので、
ここではチェックのみ行います。

routes.rb
get "search" => "searches#search"

③ モデル定義

モデルを定義します。

user.rb
  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_match"
      @user = User.where("name LIKE?","%#{word}")
    elsif search == "partial_match"
      @user = User.where("name LIKE?","%#{word}%")
    else
      @user = User.all
    end
  end
book.rb
  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_match"
      @book = Book.where("title LIKE?","%#{word}")
    elsif search == "partial_match"
      @book = Book.where("title LIKE?","%#{word}%")
    else
      @book = Book.all
    end
  end

各検索方法を下記のように指定。
検索フォーム作成時に記載した内容を見返してみてください。
・完全一致→perfect_match
・前方一致→forward_match
・後方一致→backword_match
・部分一致→partial_match

送られてきたsearchによって条件分岐させましょう。

そして、whereメソッドを使いデータベースから該当データを取得し、変数に代入します。

完全一致以外の検索方法は、
#{word}の前後(もしくは両方に)、%を追記することで定義することができます。
これにより、検索方法毎に適した検索が行われるようになりました。

④View作成

最後に、viewファイルを作成します。

検索フォームは部分テンプレートで作成します。

_search_form.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 btn-primary" %>
    <% end %>
  </div>
<% end %>

これで完成です!お疲れ様でした!
あくまで備忘録なので足りない説明等多々あるかと思います。
行き詰まった際の助けになれば幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?