Rails范围where子句似乎被缓存

时间:2017-06-01 20:22:10

标签: ruby-on-rails ruby ruby-on-rails-3 caching

使用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的值,但查询否则会动态运行。

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

2 个答案:

答案 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