単一条件の場合であれば、単に joins してあげれば、結合できないレコードは除かれるので、それで済むはず。
User.joins(:books)
User.joins(:lovers)
でも ORの複合的な条件だと、いちど LEFT OUTER JOIN をしてからじゃないt、うまくいかない気がした。
なのでまずは複数のテーブルを LEFT JOIN してから、親テーブルとの関連レコードが存在して「結合できた」ものだけを絞り込んで見た。
User
.left_joins(:books)
.left_joins(:lovers)
.where.not(books: {user_id: nil}).or(
User
.left_joins(:books)
.left_joins(:lovers)
.where.not(lovers: {user_id: nil})
)
.distinct
SQLはこんな感じ。
=> "SELECT DISTINCT `users`.* FROM `users` LEFT OUTER JOIN `books` ON `books`.`user_id` = `users`.`id` LEFT OUTER JOIN `lovers` ON `lovers`.`user_id` = `users`.`id` WHERE (`books`.`user_id` IS NOT NULL OR `lovers`.`user_id` IS NOT NULL)"
最後に distinct しているのは、has_many のテーブルを left join した時に、結果が元の user 数よりも増えるので、ユニークにしている。
Original by Github issue
チャットメンバー募集
何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。