別々の条件で取得したActiveRecord::Relationを1つにまとめようとしたら、思いの外苦労したので備忘録。
他にいい方法があれば、ぜひコメントをお願いします!
Rails 5.0以降ならorメソッド、それ以外は一度Arrayにして結合
別々の条件で取得したActiveRecord::Relationを1つにまとめる場合、merge
だとAND条件になってしまい、意図とは違う結果に。
or
というメソッドを使えばすんなり結合できるが、手元の環境はRails 4.0だったため、他の方法を模索。
+
で2つのActiveRecord::Relationを結合し、一度Arrayにした状態で再度ActiveRecord::Relationするという方法で実現。ちょっと回りくどいですが、ちゃんと書けば可読性もそこまで落ちないので、一旦この方法で落ち着きました。
users = User.where(id: [1,2,3])
another_users = User.where(name: 'John Doe')
another_users.pluck(:id) #=> [4]
# combined with AND
users.merge(another_users).to_sql
#=> SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 2, 3) AND `users`.`name` = 'John Doe'
# combined with OR (only available in Rails 5.0~)
users.or(another_users).to_sql
#=> "SELECT `users`.* FROM `users` WHERE (`users`.`id` IN (1, 2, 3) OR `users`.`name` = 'John Doe')"
# combined with OR (through Array, available in Rails ~4.0)
User.where(id: (users + another_users).map(&:id)).to_sql
#=> SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 2, 3, 4)
参考
Combine two ActiveRecord::Relation objects
[Ruby on Rails] 配列を ActiveRecord::Relation に変換する