How to use nil minimum in active record range

Viewed 441

I'm getting some inconsistent behavior in Rails 6.0.2.2 with ranges:

[49] pry(main)> Client.where(id: 1..3).limit(10).ids
   (8.0ms)  SELECT "clients"."id" FROM "clients" WHERE "clients"."id" BETWEEN $1 AND $2 LIMIT $3  [["id", 1], ["id", 3], ["LIMIT", 10]]
=> [1, 2, 3]
[50] pry(main)> Client.where(id: 1..).limit(10).ids
   (0.5ms)  SELECT "clients"."id" FROM "clients" WHERE "clients"."id" >= $1 LIMIT $2  [["id", 1], ["LIMIT", 10]]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[51] pry(main)> Client.where(id: ..3).limit(10).ids
   (0.4ms)  SELECT "clients"."id" FROM "clients" WHERE "clients"."id" BETWEEN $1 AND $2 LIMIT $3  [["id", nil], ["id", 3], ["LIMIT", 10]]
=> []

It seems like if you use a nil maximum value in a range, it works as expected by using >= in the where clause instead of between. But if you use a nil minimum value, instead of using <=, it still uses between, which returns no results. Is this an issue in ActiveRecord, and is there a recommended way around it?

1 Answers

It does look like an issue in ActiveRecord and you can get around it by using Arel or Float::INFINITY.

Client.where(Client.arel_table[:id].gte(id))
Client.where(id: Float::INFINITY..3)

The issue is solved in Rails 6.1 and is due to be backported to 6.0.

Related