Rails で 検索機能を実装する際にフルネームで検索できるように実装したい

こんにちは!kossyです!




さて、今回はRailsで検索機能を実装する際に、フルネームで検索できるようにする方法を
ブログに残してみたいと思います。




環境
Ruby 2.6.3
Rails 6.0.0
Mysql 5.7.23




前提
usersテーブルがあり、カラムとして

  • last_name
  • firlst_name
  • last_name_kana
  • first_name_kana

があるとします。
ので、full_nameというカラムを用意するのであれば今回紹介する方法を取る必要はありません。



実装手順

まずは全コード晒してみます。

app/controllers/users_controller.rb

require 'nkf'

class UsersController < ApplicationController
  KEYWORD_SIZE = 6

  def search
    _params = params.permit(:keyword)
    keywords = ["%#{NKF.nkf('-w --katakana', _params[:keyword].gsub(' ', ''))}%"] * KEYWORD_SIZE 
    query_str = 'concat(last_name, first_name) LIKE ? OR last_name LIKE ? OR first_name LIKE ? OR concat(last_name_kana, first_name_kana) like ? OR first_name_kana LIKE ? OR last_name_kana LIKE ?'
    
    @users = User.where(query_str, *keywords)
  end
end

require 'nkf' と記述しているのは、ひらがなが検索フォームに入力されても、カタカナに変換するためです。
https://qiita.com/y_minowa/items/c204992e4665a8687d4a

gsubは、文字列中の第一引数に合致するものを、第二引数に置き換えるStringクラスのメソッドです。
今回の場合は、空白(スペース)があった場合は取り除くようにしています。

%を入れているのは、あいまい検索を行うために入れています。
https://qiita.com/nakanishi03/items/2a6dbd72f9793b7e0ce4

keywordsは配列になっていて、例えばkeywordが田中だった場合、

["%田中%", "%田中%", "%田中%", "%田中%", "%田中%", "%田中%"]

のような返り値となります。

query_strはSQL句を文字列にしているもので、その中で使っているconcatは、文字列を連結させることができるmysqlの機能になります。(PostgreSQLの場合は || )
last_nameとfirst_nameをconcatする事で、フルネームでの検索を可能にしています。

\*keywordは配列を展開している動作になります。*は配列の前につけると配列を展開できる、Rubyのショートハンドになってます。
javascriptだとスプレッド構文がそれに当たりますかね。


これでひらがなでもカタカナでも漢字でもフルネームで検索ができると思います。