Inequality | Interval | Ruby range | Active Record¹ | Arel² | Description |
---|---|---|---|---|---|
x >= a | [a, ∞) | a.. | where(x: a..) | x.gteq(a) | Right unbounded closed |
x > a | (a, ∞) | n/a | where.not(x: ..a) | x.gt(a) | Right unbounded open |
x <= a | (-∞, a] | ..a | where(x: ..a) | x.lteq(a) | Left unbounded closed |
x < a | (-∞, a) | ...a | where(x: ...a) | x.lt(a) | Left unbounded open |
a <= x <= b | [a, b] | a..b | where(x: a..b) | x.between(a..b) | Closed |
a < x < b | (a, b) | n/a | where.not(x: ..a).where(x: ...b) | x.gt(a).and(x.lt(b)) | Open |
a <= x < b | [a, b) | a...b | where(x: a...b) | x.between(a...b) | Half-open left closed |
a < x <= b | (a, b] | n/a | where.not(x: ..a).where(x: ..b) | x.gt(a).and(x.lteq(b)) | Half-open right closed |
x = a | [a] | a..a | where(x: a) | x.eq(a) | Singleton |
a < x < a | ∅ | n/a³ | none⁴ | n/a | Empty |
¹When using predicate builder for Ranges, for reliable scope composition e.g. in the presence of association joins, self-joins, merges etc.
²When x = Model.arel_table[:x]
.
³An empty range in Ruby can technically be created by having the beginning greater than the end, like 1..0
, but the result has implicit type and the construction is ugly.
⁴See Active Record documentation for the none method.
The wheels come off with left-open intervals, for which Ruby has no range literal syntax.