Rails scope where 子句似乎被缓存

Rails scope where clause appears to be cached

使用 Rails 3.2.22.5,Ruby 2.0.0-p648,我有这个查询,除其他外应该 return 18 岁以下的患者:

scope :should_be_underage, joins("left join patient_status on patient_status.patient_id = patient.patient_id left join patient_state on patient_state.patient_id = patient.patient_id LEFT JOIN patient_account ON patient_account.patient_id = patient.patient_id INNER JOIN account_covers_disease ON account_covers_disease.account_id = patient_account.account_id").where("patient.dob > ?", 18.years.ago).where("((patient_state.patient_particip_status_id <> 7 and patient_account.patient_account_status = 1 and account_covers_disease.disease_id = 2) OR ((patient_status.patient_status_id not in (9, 36)) and patient_account.patient_account_status = 1 and account_covers_disease.disease_id = 1))").uniq

这运行良好,但几天前 where("patient.dob > ?", 18.years.ago) 的结果似乎已被缓存。我们正在接受 18 岁生日四天后 returned 的患者。当我人为地将其中一位患者的生日推迟一天时,他们就没有出现在结果中。当我 returned 病人到原来的生日时,他们又加入了结果。所以看起来整个查询都没有被缓存。

5 天后,我再次尝试,现在查询的是 return18 岁生日后 9 天的患者,即同一组患者。我一次又一次地尝试了人工生日重置测试,它成功了。就好像 18.years.ago 的值被缓存了,但查询动态运行。

当我重建代码库时,问题消失了,但这显然不是生产解决方案。有谁知道这里发生了什么以及我该如何纠正它?谢谢

如果缓存确实破坏了您的结果,您可以通过将查询包装在一个块中来验证这一点,如下所示:

Model.uncached do 
  # ... 
end

您 could/should 将关系表达式放在 lambda 中,以便在调用时计算日期,而不仅仅是在加载时计算

scope :should_be_underage, -> { joins(...).where(...) }

或者,您可以将表达式放在静态方法中

def self.should_be_underage
  joins(...)
    .where(...)
    .uniq
end

启动控制台并检查正在使用的查询

> Patient.should_be_underage.to_sql

在这里调用 to_sql 两次以查看 how/if 查询更改。我想目前它是不变的,但是使用 lambda 它将重新评估每个调用。