在 Rails 中,如何使用 "where" 编写比较两个日期的查找器?

In Rails, how do you write a finder with "where" that compares two dates?

我正在使用 Rails 4.2。我有一个具有这些日期时间属性的模型

submitted_at
created_at

如何编写一个 finder 方法 returns submitted_at 字段按时间顺序出现在 created_at 字段之前的所有模型?我试过这个

MyModel.where(:submitted_at < :created_at)

但这会返回我数据库中的所有内容,甚至是不匹配的项目。

您可以使用 .to_sql 查看生成的查询。

你的看起来像这样:

Resource.where(:submitted_at < :created_at).to_sql 
# => SELECT `resources`.* FROM `resources`

如果你像下面这样更新,你会得到一些结果:

Resource.where('submitted_at < created_at')
# => SELECT * FROM `resources` WHERE (submitted_at < created_at)

where(:submitted_at < :created_at)其实就是where(false)。当您将两个符号与 lt/gt 运算符进行比较时,您实际上只是按字母顺序比较它们:

:a < :b # true
:c > :b # true

where(false) 或任何其他参数 blank? 只是 returns 链接的“无作用域”关系。

ActiveRecord 查询界面并没有像这样比较列的直接方法。

您可以使用 SQL 字符串:

Resource.where('resources.submitted_at < resources.created_at')

或使用 Arel 创建查询:

r = Resource.arel_table
Resource.where(r[:submitted_at].lt(r[:created_at]))

结果完全相同,但 Arel 解决方案可以说更符合 table 并且避免了对 table 名称进行硬编码(或创建模棱两可的查询)。