ruby-on-railsrubyactiverecordarel

How can I update how ActiveRecord::Base#where interprets ranges?


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!


Solution

  • 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.