【Rails】ActiveRecordの`find_by`で大文字と小文字を区別しないで取得する方法

はじめに

find_byメソッドで値を取得する際にハマったので解決方法を探してみました。

Rails : 6.0
Ruby: 2.7
SQLite3

以上の環境で確認検証しました。


検索対象と検索したい文字列を大文字に変換

保存されたタグを取得する際、大文字と小文字の違いで期待した値を取得することができない。

$ rails console 
 # 大文字と小文字を混ぜた状態で保存します
 > Tag.create(tag_name: "RuBy")
 >
 # 小文字で先程作成したタグ名を検索してみます
 > Tag.find_by(tag_name: "ruby")
 #=> nil

Tags テーブルに保存された値は"RuBy"と保存しているためfind_byメソッドで"ruby"と検索しても取得することができません。

ユーザーがタグを検索したい場合、"ruby""Ruby""RUBY"など様々な入力で検索する可能性があるため、大文字と小文字で区別されてしまうのは不便です。


大文字と小文字を区別せずfind_byメソッドで取得するためには、SQL のupper()関数を使いカラムに含まれる文字列を大文字に変換して、検索したい文字列も Ruby の upcaseメソッドで大文字に変換して取得します。

$ rails console
# 大文字と小文字を混ぜた状態で保存します
 > Tag.create(tag_name: "RuBy")
 >
 # 検索対象のカラムと検索したい文字列をそれぞれ大文字に変換
 > Tag.find_by('UPPER(tag_name) = ?', "ruby".upcase)
 #=> tag_name: "RuBy"

これで Tags テーブルの値を大文字と小文字を区別することなく取得することができました。

'UPPER()'と大文字にしているのは SQL 的な記述のためなので、特に意味はありません upper()としても動作します。


Written by@Ryutaro
日々学習した技術系のアウトプットをしていきます。学習内容: Ruby, Ruby on Rails, Go, TypeScript, Docker

GitHub