Rails`where`的时间少于查询

Aar*_*ron 15 mysql sql ruby-on-rails date arel

建立

Rails的where方法可以在哈希中使用一个范围来生成一个查询,该查询将搜索该范围内的值.例如:

User.where(cash_money: 10..1000)
#=> SELECT `users`.* FROM `users`  WHERE (`users`.`cash_money` BETWEEN 10 AND 1000)
Run Code Online (Sandbox Code Playgroud)

这也可以用于时间戳

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')
Run Code Online (Sandbox Code Playgroud)

我发现你可以使用像这样的哈希语法做一个小于或大于数字的简单

User.where(cash_money: 10..Float::INFINITY)
#=> SELECT `users`.* FROM `users`  WHERE (`users`.`cash_money` >= 10)
Run Code Online (Sandbox Code Playgroud)

同样可以-Float::INFINITY用于少于查询.

有没有办法用时间戳来做到这一点所以我可以得到如下的查询?

SELECT `users`.* FROM `users`  WHERE (`users`.`last_deposit` >= '2014-05-19 14:42:36')
Run Code Online (Sandbox Code Playgroud)

我不能使用Float::INFINITYDate::Infinity使用范围,因为他们都错误ArgumentError: bad value for range.

当前的简单解决方

User.where('`users`.`last_deposit` >= ?', 10.days.ago)
Run Code Online (Sandbox Code Playgroud)

将生成相同的SQL,但如果这可以使用字符串以外的对象完成,我想这样做.

潜力(Meh)答案

这有点糟糕但可以使用Time.at(0)和使用范围来完成Time.at(Float::MAX).我觉得这些可能导致同样糟糕的SQL查询.

Aar*_*ron 13

编辑

这在Rails 5中现在可以实现!

User.where(last_deposit: 10.days.ago..DateTime::Infinity.new)
Run Code Online (Sandbox Code Playgroud)

将生成SQL

SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` >= '2018-06-30 17:08:54.130085').
Run Code Online (Sandbox Code Playgroud)

原始(和Rails <5)答案

看起来似乎没有办法使用基本where哈希语法来生成大于或小于时间戳的查询.最简单,最易阅读的方式在我的问题中概述Current Simple Solution.

另一种方法是使用ARel,但你必须做一些不太常见的调用.首先,您可以获取AR类的ARel表的句柄,访问该列,使用参数传递大于gt,大于或等于gteq,小于lt和/或小于或等于lteq方法的结果where.

在上面的情况中,这将完成如下:

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)
Run Code Online (Sandbox Code Playgroud)

  • Ruby 2.6+ 中引入了无限范围,Ruby 2.7 中引入了无限范围,因此您的系统没有任何问题。 (2认同)

Ric*_*ard 10

你试过这个吗?:

User.where(last_deposit: Time.at(0)...10.days.ago)
Run Code Online (Sandbox Code Playgroud)

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')
Run Code Online (Sandbox Code Playgroud)

  • 范围限制之间的三个点使您在 'from' 值上获得 &gt;= ,在 'to' 值上获得 'AND &lt;' 。两个点使用“from”和“to”为您提供“BETWEEN”sql查询。(在 Rails 4.0.13 中) (2认同)