Rails`where`for time less than 查询
问题:Railswherefor time less than 查询 设置 Rails 的where方法可以采用散列中的一个范围来生成一个查询,该查询将搜索该范围内的值。例如: User.where(cash_money: 10..1000) #=> SELECT `users`.* FROM `users` WHERE (`users`.`cash_money` BETWEEN 10 AND 1
问题:Railswhere
for time less than 查询
设置
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 查询。
解答
编辑 2 5/9/20
如果您使用的是 Ruby 2.6,则可以使用无限范围来执行此操作,而在 Ruby 2.7 中,您可以使用无开始范围。
例如:
# Ruby >= 2.6
User.where(last_deposit: 10.days.ago..)
生成
SELECT "users".* FROM "users" WHERE "user"."last_deposit" >= '2020-04-29 21:58:39.109419'"
和
# Ruby >= 2.7
User.where(last_deposit: ..10.days.ago)
生成
SELECT "users".* FROM "users" WHERE "users"."last_deposit" <= '2020-04-29 22:01:05.582055'
编辑
现在这在 Rails 5 中成为可能!
User.where(last_deposit: 10.days.ago..DateTime::Infinity.new)
将生成 SQL
SELECT `users`.* FROM `users` WHERE (`users`.`last_deposit` >= '2018-06-30 17:08:54.130085').
原始(和 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)
更多推荐
所有评论(0)