It appears that ActiveRecord::Base#where
partially distinguishes between ranges defined with 2 dots (0..
) and ranges defined with 3 dots (0...
).
E.g.
> User.where(id: ..0).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" <= 0"
> User.where(id: ...0).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" < 0"
Notice how the query defined with 3 dots use <
compared to the query defined with 2 dots which uses <=
.
This is a great feature, however, I've noticed this doesn't seem to be working with ranges with no top:
> User.where(id: 0..).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" >= 0"
> User.where(id: 0...).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" >= 0"
In this case, >=
is used regardless of the number of dots.
I would like to submit a patch to the Rails gem to fix this, but I can't for the life of me figure out where this interpretation is happening. I'm assuming it occurs somewhere in Arel, but so far I have not been able to find it.
If anyone can help guide me I would much appreciate it!
Thank you @Alex for the explanation!
It looks like this is because Ruby defines a ...
range to exclude the end of the range, but to includes the beginning of the range.
So in the case of ...0
, zero is excluded resulting in <
.
In the case of 0...
, zero is included resulting in >=
.
This is still counter-intuitive to me, but sounds like something I'd need to take up with the Ruby crew.