Rails `where` for time less than queries

前端 未结 4 1877
礼貌的吻别
礼貌的吻别 2020-12-28 18:13

Setup

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:

相关标签:
4条回答
  • 2020-12-28 18:30

    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')
    
    0 讨论(0)
  • 2020-12-28 18:35

    Try this:

    User.where(last_deposit.gt(10.days.ago))
    
    0 讨论(0)
  • 2020-12-28 18:44

    Edit 2 5/9/20

    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'
    

    Edit

    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').
    

    Original (and Rails < 5) Answer

    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)
    
    0 讨论(0)
  • 2020-12-28 18:44

    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?

    0 讨论(0)
提交回复
热议问题