🙆
Rails で関連先と紐付いていないレコードを取得する
例えば『まだコメントしていないユーザを絞り込む』みたいなことをしたい場合に以下のように .left_joins
+ .where
で絞り込む、で実現することができます。
class User < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
end
# 必要なデータを生成
User.create(name: "homu").tap {
_1.comments.build(text: "OK").save!
_1.comments.build(text: "NICE").save!
}
User.create(name: "saya").tap {
_1.comments.build(text: "oops").save!
}
User.create(name: "mami")
User.create(name: "mado")
# こんな感じで『comments が存在しない user』を絞り込むことができる
User.left_joins(:comments).where(comments: { id: nil }).tap {
puts _1.to_sql
# => SELECT "users".*
# FROM "users"
# LEFT OUTER JOIN "comments"
# ON "comments"."user_id" = "users"."id"
# WHERE "comments"."id" IS NULL
pp _1.pluck(:name)
# => ["mami", "mado"]
}
また Rails 6.1 以降では where.missing
が利用できます。
# User.left_joins(:comments).where(comments: { id: nil }) と同等
User.where.missing(:comments).tap {
puts _1.to_sql
# => SELECT "users".*
# FROM "users"
# LEFT OUTER JOIN "comments"
# ON "comments"."user_id" = "users"."id"
# WHERE "comments"."id" IS NULL
pp _1.pluck(:name)
# => ["mami", "mado"]
}
Discussion