设置
Rails的where
方法可以接受一个散列中的范围来生成一个查询,该查询将搜索该范围内的值。例如:
User.where(cash_money: 10..1000)
#=> SELECT `users`.* FROM `users` WHERE (`users`.`cash_money` BETWEEN 10 AND 1000)
这也可以与时间戳一起使用,如
User.where(last_deposit: 10.days.ago..1000.days.ago)
#=> SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` BETWEEN '2014-05-19 14:42:36' AND '2011-09-02 14:42:36')
我发现,可以使用像这样的哈希语法对数字执行简单的小于或大于操作
User.where(cash_money: 10..Float::INFINITY)
#=> SELECT `users`.* FROM `users` WHERE (`users`.`cash_money` >= 10)
并且对于小于查询,可以用-Float::INFINITY
完成相同的操作。
问题
有没有一种方法可以用时间戳来做这件事,这样我就可以得到一个像下面这样的查询?
SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` >= '2014-05-19 14:42:36')
我不能使用Float::INFINITY
或Date::Infinity
与范围,因为它们都与ArgumentError: bad value for range
错误。
当前简单方案
User.where('`users`.`last_deposit` >= ?', 10.days.ago)
将生成相同的SQL,但如果这可以用字符串以外的对象完成,我想这样做。
潜在(Meh)答案
这有点糟糕,但可以使用Time.at(0)
和Time.at(Float::MAX)
的范围来完成。我有一种感觉,这些可能会导致同样糟糕的SQL查询。
5条答案
按热度按时间nzk0hqpo1#
编辑2 5/9/20
如果你使用的是Ruby 2.6,你可以使用无限的范围,而在Ruby 2.7中,你可以使用无开始的范围。
例如:
生成
以及
生成
编辑
这在Rails 5中是可能的!
将生成SQL
Original(and Rails〈5)Answer
似乎没有一种方法可以使用基本的
where
哈希语法来生成一个大于或小于时间戳的查询。最简单和最可读的方法在我的问题Current Simple Solution
中概述。另一种方法是使用ARel,但你必须进行一些不太常见的调用。首先,你可以获得AR类的ARel表的句柄,访问列,将大于
gt
,大于或等于gteq
,小于lt
和/或小于或等于lteq
方法的结果与参数传递给where
。在上述情况下,这将像这样完成:
mctunoxg2#
你试过这个吗?:
SQL语句:
3lxsmp7m3#
你需要使用合适的无穷大。时间戳是
DateTime
而不是Date
。使用DateTime::Infinity.new
代替,或者使用DateTime::Infinity.new(-1)
表示负无穷大。相关:Is there a way to express 'Infinite Time' in Ruby?
insrf1ej4#
Rails 5(和Ruby〈2.7)
User.where(last_deposit: 10.days.ago.to_datetime..DateTime::Infinity.new)
这也应该起作用:
User.where(last_deposit: 10.days.ago..DateTime::Infinity.new)
但在某个日期之前有问题的范围:
User.where(last_deposit: DateTime::Infinity.new..10.days.ago.to_datetime)
DateTime::Infinity.new现在等于Float::INFINITY。Time.current(所以3.minutes.ago也是)不支持Float的范围。
将其转换为日期时间可以解决这个问题
fjaof16o5#
试试这个: