【Rails】whereメソッドの使い方を徹底解説!基本構文からnot・or・LIKE検索まで実例付き
Railsでは、モデルを介してデータベースにクエリを発行することで、アプリ内のデータへアクセスします。このとき使用するのが、ActiveRecordが提供する各種メソッドです。
代表的なメソッドには、where、find、find_byがあります。
それぞれの戻り値は次のとおりです。
find_by:条件に一致する1件のレコード、またはnilを返すwhere:ActiveRecord::Relationオブジェクトを返すfind:主キー(通常はid)をもとに1件のレコードを返す。見つからない場合は例外を発生させる
つまり、特定のユーザーのように「1件だけ」欲しい場合はfind_byを、ユーザーの一覧のように「複数件」欲しい場合はwhereを使う、という使い分けになります。
ただし、whereにはさまざまな書き方があり、初心者を混乱させがちです。
ご安心ください。この記事では、Railsアプリケーションでwhereを使うさまざまなパターンを、実例とともにわかりやすく解説していきます。
基本的なwhere条件の書き方
whereの目的は、データベース内の情報を絞り込むクエリを組み立て、必要な行だけを取得することです。
たとえば、title(タイトル)、author(著者)、category(カテゴリ)というカラムを持つBookモデルがあるとしましょう。
「特定の著者の本をすべて知りたい」「特定のカテゴリに分類された本をすべて知りたい」といったケースで活躍します。
具体的なクエリはこちら。
Book.where(category: "Ruby")
これは、カテゴリが「Ruby」であるすべての本を返します。
条件は複数組み合わせることも可能です。
Book.where(category: "Ruby", author: "Jesus Castello")
この場合、カテゴリと著者の両方に一致する本だけが返されます。
さらに、whereはスコープ(scope)とも組み合わせられます。
# スコープの定義
class Book
scope :long_title, -> { where("LENGTH(title) > 20") }
end
# コントローラーのコード
@books = Book.long_title.where(category: "Ruby")
ハッシュ形式(fruit: "apple"のような書き方)では、「あるカラムが特定の値と等しいか」をチェックできます。
しかし、「等しい」以外の条件で検索したい場合はどうすればよいのでしょうか?
その場合は、文字列形式を使うことになります。
大小比較(より大きい・より小さい)
「〜より大きい」「〜より小さい」といった比較条件を指定したい場面も多いでしょう。
その場合は次のように書きます。
Book.where("LENGTH(title) > 20")
値を動的に埋め込みたい(補間したい)場合は、こうします。
Book.where("LENGTH(title) > ?", params[:min_length])
この?は「プレースホルダー」と呼ばれるもので、SQLインジェクション攻撃を防ぐためのセキュリティ対策として使われます。
もうひとつの選択肢として、名前付きプレースホルダーもあります。
例:
Book.where("LENGTH(title) > :min", min: params[:min_length])
一般的には疑問符プレースホルダーのほうがよく使われますが、補間する値が多い複雑なクエリでは、名前付きプレースホルダーのほうが可読性が高くなることもあります。
not・orメソッドとの組み合わせ
ここからは、少し複雑なクエリを見ていきましょう。
「ある条件が成り立たない」ことをチェックしたい場合は、whereにnotメソッドを組み合わせます。
例:
Book.where.not(category: "Java")
別の例:
Book.where.not(title: nil)
これは、titleがnilではないBookレコードを検索します。
OR条件はどう書くのか?
whereにorメソッドを組み合わせると、2つ以上の条件のうちどれか1つでも一致する行を取得できます。
書き方はこちら。
Book.where(category: "Programming").or(Book.where(category: "Ruby"))
このように、2つのwhereクエリを1つにまとめることができます。
ぜひ実際に試してみてください。
配列を使ったIN検索
これまでの例では、すべて1つの特定の値を検索していました。
しかし、複数の値を同時に検索したいこともありますよね。
その方法は?
答えは「配列」です!
例:
Book.where(id: [1,2,3])
これにより、指定したすべてのIDを一度に検索する「IN」クエリが生成されます。
SELECT "books".* FROM "books" WHERE "books"."id" IN (1, 2, 3)
生成されたSQLは、Railsのログで確認できます。
joinsを使った関連先の条件指定
関連付けられたモデルの値をもとに検索したい場合は、まずjoinsメソッドでその関連を利用できるようにする必要があります。
そのうえで、次のように書けます。
Book.joins(:comments).where(comments: { id: 2 })
このクエリは、「コメントを持っていて、そのコメントのidが2である」すべての本を取得します。
文字列形式で書くと:
Book.joins(:comments).where("comments.id = 2")
ここでcommentsはテーブル名、idはカラム名です。
LIKE句による部分一致検索
検索機能を実装するなら、「部分一致」で検索できるようにしたいことがあります。
そんなときに使えるのが「LIKE」クエリです。
例:
Book.where("title LIKE ?", "%" + params[:q] + "%")
このクエリは、params(params[:q])で渡された検索キーワードが、タイトル内のどこかに含まれているすべての本を検索します。
検索機能には欠かせない、とても便利なクエリです。
%記号とは何か?
SQLにおいて、%はワイルドカード文字です。「任意の0文字以上の文字列」にマッチします。
まとめ
この記事では、Railsのwhereメソッドを使ってActiveRecordモデルをクエリする方法を学びました!
学んだ内容:
- 複数の条件で絞り込む方法
- 配列を使って複数の行を効率的に検索する方法
or・notメソッドと組み合わせて、より複雑なクエリを書く方法
ぜひ、あなたのプロジェクトで実際に試してみてください。
最後までお読みいただきありがとうございました🙂
-
Rubyのmapメソッド完全ガイド!配列・ハッシュのデータ変換を実例で解説
Rubyのmapメソッドは、配列(Array)・ハッシュ(Hash)・範囲(Range)といったコレクションに対して使用できる強力なメソッドです。 mapの主な用途は、データの変換です。 例えば、文字列の配列があった場合、すべての文字列を順番に処理して、各文字を大文字に変換することができます。 また、Userオブジェクトのリストがある場合も同様です。 それらを変換して、対応するメールアドレスや電話番号など、Userクラスに定義された任意の属性のリストを作成できます。 それでは、具体的な使い方を見ていきましょう! Ruby mapメソッドの基本構文 mapの構文は次のようになっています。 a
-
Linuxのwatchコマンドの使い方と実用例をわかりやすく解説
Linuxのwatchコマンドは、指定したコマンドを一定間隔で繰り返し実行し、その結果を画面に表示し続けるためのツールです。コマンドの出力が時間とともにどう変化するかをリアルタイムで監視したい場合に非常に便利です。この記事では、watchコマンドの基本的な使い方と、覚えておくと役立つ実用的な例を紹介します。 watchコマンドの基本構文 watchコマンドの構文は以下のとおりです。 watch オプション コマンド 各要素の意味は次のとおりです。 オプション: 後述の表から選択したオプションを指定します。watchコマンドのデフォルト動作を変更できます。 コマンド: watchが繰り返し実行