nesheep5's blog

子持ちWebエンジニアのブログ。プログラミング・仕事効率化・健康・子育て etc...

ActiveRecordでの範囲指定検索

ActiveRecordでBETWEEN的な範囲指定検索をしたいケースがあり、挙動を調べたので整理してみました。 ( ※Rails 5.2.0, MySqlで確認しています。)

以下のようにRangeで表現することができます。

User.where(id: from..to)

通常の範囲指定

検索条件に1..10を指定すると、BETWEEN句に変換してくれます。

User.where(id: 1..10)
SELECT  `users`.* FROM `users` WHERE `users`.`id` BETWEEN 1 AND 10 LIMIT 11

from以上

toにFloat::INFINITYを指定すると、BETWEEN句ではなく空気を読んでid >= 1に変換してくれます。すごい!

User.where(id: 1..Float::INFINITY)
SELECT  `users`.* FROM `users` WHERE `users`.`id` >= 1 LIMIT 11

to以下

逆にfromFloat::MINを指定すると、idの最小値=0に置き換え(DBの型から判別してる?)、BETWEEN句に変換してくれます。

User.where(id: Float::MIN..10)
SELECT  `users`.* FROM `users` WHERE `users`.`id` BETWEEN 0 AND 10 LIMIT 11

from/toが同値

from/toに同値を指定すると、BETWEEN 1 AND 1となりました。
id = 1を期待していたのですが、1件なら性能も大差ないでしょうし問題なさそうです。

User.where(id: 1..1)
SELECT  `users`.* FROM `users` WHERE `users`.`id` BETWEEN 1 AND 1 LIMIT 11

おすすめの範囲指定

上記の挙動をふまえ、以下のようなコードに落ち着きました。

from = query.id_from.blank? ? Float::MIN : query.id_from
to = query.id_to.blank? ? Float::INFINITY : query.id_to
User.where(id: from..to)

ActiveRecordは便利な機能がたくさんあって面白いですね!しっかり勉強していこうと思います。
もっとスマートな書き方あるよ!という方いましたらぜひ教えてください!

広告を非表示にする