背景
railsでdistinctとin_batchesを同時に利用すると、正しい値が取得できなかったので解説する
内容
User.select(:user_id).distinct.in_batches(of: 2) { p _1.pluck(:id)}
の挙動について
usersテーブルに1~5のidを持つレコードが格納されているとした時、
[1,2]
[3,4]
[5]
と出力されると期待していたが
[1,3]
[1,2]
[4,5]
のように値が重複して出力されてしまった
User.select(:user_id).distinct.in_batches(of: 2) { p _1.pluck(:id)}
の挙動について
ChatGPTに確認したところ、
ActiveRecordでdistinctを使用して一意なレコードを取得した後にin_batchesを使用すると、クエリの処理方法によっては重複した値が含まれる場合があります。これは、in_batchesがページング処理を行う際にdistinctが適用される前の段階で重複が発生することが原因です。
ということだったので、
User.select(:id).distinct.offset(offset).limit(batch_size).pluck(:user_id)
のように書き直しました
結論
distinctを使用する場合は、limit, offsetを使いましょう