Rails\' where
method can take a range in a hash to generate a query that will search for a value that is within the range. For example:
Did you try this?:
User.where(last_deposit: Time.at(0)...10.days.ago)
SQL:
SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` >= '1970-01-01 00:00:00' AND `users`.`last_deposit` < '2015-01-10 17:15:19')
Try this:
User.where(last_deposit.gt(10.days.ago))
If you are using Ruby 2.6 you can do this with endless ranges and in Ruby 2.7 you can use begin-less ranges.
E.g.:
# Ruby >= 2.6
User.where(last_deposit: 10.days.ago..)
generates
SELECT "users".* FROM "users" WHERE "user"."last_deposit" >= '2020-04-29 21:58:39.109419'"
and
# Ruby >= 2.7
User.where(last_deposit: ..10.days.ago)
generates
SELECT "users".* FROM "users" WHERE "users"."last_deposit" <= '2020-04-29 22:01:05.582055'
This is now possible in Rails 5!
User.where(last_deposit: 10.days.ago..DateTime::Infinity.new)
will generate the SQL
SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` >= '2018-06-30 17:08:54.130085').
It does not appear as if there is a way to use basic where
hash syntax to generate a greater than or less than query for timestamps. The simplest and most readable way is outlined in my question under Current Simple Solution
.
Another way to do it makes use of ARel but you have to make some less commonly seen calls. First you can get a handle to the AR class' ARel table, access the column, pass the result of the greater than gt
, greater than or equal to gteq
, less than lt
, and/or less than or equal to lteq
method with an argument to where
.
In the situation above this would be done like:
last_deposit_column = User.arel_table[:last_deposit]
last_deposit_over_ten_days_ago = last_deposit_column.gteq(10.days.ago)
User.where(last_deposit_over_ten_days_ago)
You need to use the appropriate infinity. A timestamp is a DateTime
not a Date
. Use DateTime::Infinity.new
instead or DateTime::Infinity.new(-1)
for negative infinite.
Related: Is there a way to express 'Infinite Time' in Ruby?