🐣

[Ruby on Rails] 検索機能の作成

2023/07/07に公開

コントローラーの作成

$ rails g controller searches search
searches_controller
  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

解説

  • params formから送られてくるデータが入っています
  • インスタンス変数にそれぞれのデータを入れています
  • if文を使用し、 @model が user だった場合と book だった場合で条件分岐します

ルーティングの記述

routes.rb
get '/search', to 'searches#search'

検索フォームのフォームの作成

今回はヘッダーに入れて、全画面で使用できるようにしたいので、部分テンプレートにします。
views/layouts/_search.html.erb を作成

_search.html.erb
<div class="search_form">
  <%= 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 %>
</div>

解説

form_with
  • url 書き方は form_with url: url_path となり、 urlに POST(新しいデータ作成) を送信する
  • method: :get でデータの取得をさせます
  • local: true 通常のHTTPリクエストとなり、ページ全体がリロードされるよになる
  • f.text_field 単行の入力欄を作成し、 content テーブルに渡す
f.select
  • f.select プルダウン(セレクトボックス)を作成する :model で何のプルダウンか指定
  • options_for_select プルダウンの中身を指定します
  • ({" プルダウンで表示する文字 " => " DBに渡す値(モデル名など) "}) となる
  • 今回は使用しませんでしたが、 include_blank: "選択" などを追加すると、デフォルトの選択肢を 選択 にしておくこともできます

モデルに検索条件の分岐を書く

book.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 オブジェクトそのものを指している 今回は Bookのオブジェクトになる
  • (content, method) 入力された値と、選択された条件が入る
  • where メソッドはテーブル内の条件に一致したレコードを配列の形で取得することができるメソッド
  • ` モデル名.where('条件') ' と書く
  • LIKE ? あいまい検索
  • モデル.where('配列名 LIKE ? , '% 値 %') と書く
    値を含むという意味になる

Userモデルにも同じ様に書きます

user.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

これで完成です

こちらの記事を参考にさせていただきました

Discussion