大文字小文字を区別しないでActiveRecord(where)で取得する方法
大文字小文字を区別しないでActiveRecord(where)で取得する方法
■ モデル構造
Personテーブルから名前がstevejobsのレコードを検索取得したい場合
モデルクラス.where("列名 LIKE ?", "%値%") # 値(文字列)を含む
で取得できるので以下のように実装します。
Person.where("name like ?", "%stevejobs%") # 値(文字列)を含む
これでnameがstevejobsのレコードが取得できます。
しかし検索する時に英語の大文字小文字を区別したいケースに遭遇しました。
例) 人物テーブルからステーブジョブスを検索したい場合
Aさん -> "SteveJobs"と検索 Bさん -> "stevejobs"と検索
現在の実装ではstevejobs
と検索しているのでBさんの検索方法でしかヒットしません。
arel_tableを利用する。
色々調査した結果、Active Recordの内部で使用されるSQL生成ライブラリArelを利用すれば実現可能ということがわかりました。
Arelを使うと文字列でSQLを書くことなく、Rubyのコードとしてクエリを書くことができます。
arelではmatchesを使う事でlikeクエリが書けるので以下のように変更します。
persons = Person.arel_table persons.where(persons[:name].matches("%name%"))
matchesメソッドではデフォルトでcase_sensitive = false
と設定されているので大文字小文字を区別しません。
def matches(other, escape = nil, case_sensitive = false) Nodes::Matches.new self, quoted_node(other), escape, case_sensitive end
これで、AさんパターンBさんパターンのどちらもヒットします。
環境
Rails 6.0.1 ruby 2.6.5p postgres:11.2