以下の内容はhttps://kamatimaru.hatenablog.com/entry/2025/12/27/104204より取得しました。


よく使うSQLの条件のActiveRecordでの書き方

本記事ではよく使うSQLの条件のActiveRecordでの書き方をまとめます

AND条件で検索

シンプルにwhereメソッドにカンマで条件を追加するとAND条件になります。

コード1

Tag.where(name: "南インド", position: 1)

結果1

app(dev):002> Tag.where(name: "南インド", position: 1)
  Tag Load (6.6ms)  SELECT "tags".* FROM "tags" WHERE "tags"."name" = '南インド' AND "tags"."position" = 1 /* loading for pp */ LIMIT 11 /*application='App'*/
=>
[#<Tag:0x0000ffff82fd1420
  id: 1,
  created_at: "2025-11-03 00:17:07.271876000 +0000",
  name: "南インド",
  position: 1,
  updated_at: "2025-11-03 00:17:07.271876000 +0000",
  tag_group_id: 1>]

コード2

whereを連結させても同じ挙動になります。where条件をif文で分けたい場合や後述の大小比較のように1つのwhereメソッドの中身が煩雑になる場合はこちらの書き方がよさそうです。

Tag.where(name: "南インド").where(position: 1)

結果2

app(dev):010> Tag.where(name: "南インド").where(position: 1)
  Tag Load (15.5ms)  SELECT "tags".* FROM "tags" WHERE "tags"."name" = '南インド' AND "tags"."position" = 1 /* loading for pp */ LIMIT 11 /*application='App'*/
=>
[#<Tag:0x0000ffff80685c88
  id: 1,
  created_at: "2025-11-03 00:17:07.271876000 +0000",
  name: "南インド",
  position: 1,
  updated_at: "2025-11-03 00:17:07.271876000 +0000",
  tag_group_id: 1>]

OR条件で検索

OR条件の方が書き方が複雑です。orメソッド内にクエリをもう1つ書きます。

https://railsguides.jp/active_record_querying.html#or条件

コード

Tag.where(name: "南インド").or(Tag.where(position: 3))

結果

app(dev):004> Tag.where(name: "南インド").or(Tag.where(position: 3))
  Tag Load (0.7ms)  SELECT "tags".* FROM "tags" WHERE ("tags"."name" = '南インド' OR "tags"."position" = 3) /* loading for pp */ LIMIT 11 /*application='App'*/
=>
[#<Tag:0x0000ffff77460510
  id: 1,
  created_at: "2025-11-03 00:17:07.271876000 +0000",
  name: "南インド",
  position: 1,
  updated_at: "2025-11-03 00:17:07.271876000 +0000",
  tag_group_id: 1>,
 #<Tag:0x0000ffff774603d0
  id: 2,
  created_at: "2025-11-03 00:42:55.770481000 +0000",
  name: "ビリヤニ",
  position: 3,
  updated_at: "2025-11-03 01:57:44.855153000 +0000",
  tag_group_id: 3>]

IS NULL

wherenilを渡すだけでOKです。

コード

Tag.where(name: nil)

結果

app(dev):022> Tag.where(name: nil)
  Tag Load (43.0ms)  SELECT "tags".* FROM "tags" WHERE "tags"."name" IS NULL /* loading for pp */ LIMIT 11 /*application='App'*/
=> []

IN句

whereに渡す値をスカラーから配列にするだけでIN句を実現できます。

コード

Tag.where(name: ["南インド","ビリヤニ"])

結果

app(dev):018> Tag.where(name: ["南インド","ビリヤニ"])
  Tag Load (4.4ms)  SELECT "tags".* FROM "tags" WHERE "tags"."name" IN ('南インド', 'ビリヤニ') /* loading for pp */ LIMIT 11 /*application='App'*/
=>
[#<Tag:0x0000ffff80682088
  id: 1,
  created_at: "2025-11-03 00:17:07.271876000 +0000",
  name: "南インド",
  position: 1,
  updated_at: "2025-11-03 00:17:07.271876000 +0000",
  tag_group_id: 1>,
 #<Tag:0x0000ffff80681f48
  id: 2,
  created_at: "2025-11-03 00:42:55.770481000 +0000",
  name: "ビリヤニ",
  position: 3,
  updated_at: "2025-11-03 01:57:44.855153000 +0000",
  tag_group_id: 3>]

結合先のテーブルのwhere条件で絞り込む

以下のような書き方をします。

  • joinsの引数のtags: アソシエーション名
  • whereのキーのtags: テーブル名

なのがポイントです。

コード1

TagGroup.joins(:tags).where(tags: { name: "南インド" })

結果

app(dev):015> TagGroup.joins(:tags).where(tags: { name: "南インド" })
  TagGroup Load (6.8ms)  SELECT "tag_groups".* FROM "tag_groups" INNER JOIN "tags" ON "tags"."tag_group_id" = "tag_groups"."id" WHERE "tags"."name" = '南インド' /* loading for pp */ LIMIT 11 /*application='App'*/
=>
[#<TagGroup:0x0000ffff77e0c690
  id: 1,
  name: "テスト",
  position: 1,
  created_at: "2025-11-02 14:58:36.249161000 +0000",
  updated_at: "2025-11-02 14:58:36.249161000 +0000">]

コード2

1対Nの関連の場合は、joinsに渡す引数がテーブル名の単数系のシンボルになります。

Restaurant.joins(:prefecture).where(prefectures: {name: "東京都"})

whereの大小比較(<, =<)

大小比較を直接表現するメソッドは用意されていないので、条件を文字で書いてプレースホルダーで比較対象の値を渡します。

コード1

 Tag.where("position < ?", 2)

結果

app(dev):006> Tag.where("position < ?", 2)
  Tag Load (1.4ms)  SELECT "tags".* FROM "tags" WHERE (position < 2) /* loading for pp */ LIMIT 11 /*application='App'*/
=>
[#<Tag:0x0000ffff7744c1c8
  id: 1,
  created_at: "2025-11-03 00:17:07.271876000 +0000",
  name: "南インド",
  position: 1,
  updated_at: "2025-11-03 00:17:07.271876000 +0000",
  tag_group_id: 1>]

コード2

小なりイコールにしたい場合は、<<=にします。

 Tag.where("position <= ?", 2)

LIKE検索

LIKE検索も同様に直接表現するメソッドは用意されていないので、条件を文字で書いてプレースホルダーで比較対象の値を渡します。

コード

Tag.where("name LIKE ?", "%インド")

結果

app(dev):013> Tag.where("name LIKE ?", "%インド")
  Tag Load (0.5ms)  SELECT "tags".* FROM "tags" WHERE (name LIKE '%インド') /* loading for pp */ LIMIT 11 /*application='App'*/
=>
[#<Tag:0x0000ffff77449248
  id: 1,
  created_at: "2025-11-03 00:17:07.271876000 +0000",
  name: "南インド",
  position: 1,
  updated_at: "2025-11-03 00:17:07.271876000 +0000",
  tag_group_id: 1>]

否定系

notメソッドを使います。

コード

Tag.where.not(name: "南インド")

結果

app(dev):023> Tag.where.not(name: "南インド")
  Tag Load (11.0ms)  SELECT "tags".* FROM "tags" WHERE "tags"."name" != '南インド' /* loading for pp */ LIMIT 11 /*application='App'*/
=>
[#<Tag:0x0000ffff77463c10
  id: 2,
  created_at: "2025-11-03 00:42:55.770481000 +0000",
  name: "ビリヤニ",
  position: 3,
  updated_at: "2025-11-03 01:57:44.855153000 +0000",
  tag_group_id: 3>]



以上の内容はhttps://kamatimaru.hatenablog.com/entry/2025/12/27/104204より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14