ひーろのアウトプットブログ

プログラミングの学習記録と開発日記です

where句で「_」を検索する方法

ユーザーの検索でSQL文を使い、_(アンダースコア)から始まるユーザーネームを検索しようとした際に、少し困ったので書いておきます。

なんで困ったの?

まずスコープを作って検索の共通化をしました。

class User < ApplicationRecord
  scope :search_user, ->(name) { where('name like?', "#{name}%") }
end

こんな感じのスコープで、任意の場所で検索をかけます。
@users.search_user('_')と記述したところ、結果は全検索となりました。
欲しい結果はアンダースコアから始まるユーザーです。
原因を考えていたところ、そういえばSQLにはワイルドカードなんてのがあったなと思い出し調べてみました。

ワイルドカード

LIKE句で使えるワイルドカードは2種類あります。

%……0文字以上の任意の文字列
_…任意の1文字

なるほど。ワイルドカードで検索をしてしまったようです。
@users.search_user('_')の意味するところは、任意の1文字を何もない文字に指定したので、結果的に全検索になっていました。

解決策

アンダースコアから始まる名前を検索するにはエスケープ文字を使ってあげれば良いです。
ワイルドカードである「_」の前に、バックスラッシュを書いてあげれば正しく検索できます。

@users.search_user('\_')

これで欲しい結果を得ることができました。

参考

http://www.sql-reference.com/select/like.html https://rooter.jp/programming/ruby/rails_use_where_or_sanitize_sql_methods_to_avoid_sql_injection/
https://itsakura.com/sql-select-like