使用Rails 3.2.22.5,Ruby 2.0.0-p648,我有这个查询,其中包括应该返回不到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
这样运行正常,但几天前似乎缓存了(&#34; patient.dob&gt;?&#34;,18.years.ago)的结果。我们得到了18岁生日后四天回来的病人。当我每天人工设置一个患者的生日时,他们就没有结果了。当我将患者送回原来的生日时,他们再次加入了结果。因此,整个查询似乎没有被缓存。
五天后,我再次尝试,现在询问是在他们18岁生日后9天返回患者,即同一组患者。我一次又一次地尝试了人工生日重置测试。它好像只是缓存了18.years.ago的值,但查询否则会动态运行。
当我重建代码库时,问题就消失了,但这显然不是生产解决方案。有谁知道这里发生了什么以及我如何纠正它?感谢。
答案 0 :(得分:1)
您可以/应该将关系表达式放在lambda中,以便在调用时评估日期,而不仅仅是在加载时
scope :should_be_underage, -> { joins(...).where(...) }
或者,您可以将表达式放在静态方法
中def self.should_be_underage
joins(...)
.where(...)
.uniq
end
启动控制台并检查正在使用的查询
> Patient.should_be_underage.to_sql
在此处拨打to_sql
两次以查看查询如何更改/是否更改。我想现在它不变,但是有一个lambda,它将重新评估每个电话。
答案 1 :(得分:0)
如果缓存确实打破了您的结果,您可以通过将查询包装在如下的块中来验证这一点:
Model.uncached do
# ...
end