轨道上的红宝石 - Sum 在应返回 0 时返回值



我遇到了一个非常令人困惑的问题。在这里:

[12] pry(EstimatedTime)> EstimatedTime.where(user_id: User.current.id, plan_on: date).pluck(:hours) => [] 
[13] pry(EstimatedTime)> EstimatedTime.where(user_id: User.current.id, plan_on: date).sum(:hours) => 3.0

这是什么魔力?

此语句驻留在从视图中调用的模型方法中。在此之前,在控制器操作中,我调用了相同模型的另一种方法,即在事务中执行记录的批量创建。

def self.save_all(records)
  transaction do
    records.each do |record|
      record.save!
    end
  end
  rescue ActiveRecord::RecordInvalid
    return false 
end

引发异常,方法返回 false,呈现视图并发生这种情况。

UPD我找到了一种解决方法,将.sum替换为.pluck(:hours).sum,但我仍然不知道为什么我的第一种方法失败了。

正如David Aldrige在对该问题的评论中指出的那样,问题在于.sum(:hours)正在使用缓存的数据,而.pluck(:hours)实际上是在研究数据库。

为什么数据库和查询缓存包含不同的数据?好吧,似乎在 Rails 3 中(我应该在提问时指定我的 rails 版本)失败的事务会回滚数据库,但保持查询缓存不变。这导致数据库和缓存之间的临时数据不一致。如本期所述,此问题已在 Rails 4 中得到纠正。

解决方案1,也就是我为自己选择的解决方案

事务失败后清除查询缓存。因此,在事务中执行批量插入的方法现在如下所示:

def self.save_all(records)
  transaction do
    records.each do |record|
      record.save!
    end
  end
  rescue ActiveRecord::RecordInvalid
     self.connection.clear_query_cache
     return false 
end

解决方案 2

个人觉得这不那么优雅,尽管我无法在性能方面比较这些解决方案,所以我会同时发布它们。可以简单地这样写 sum 语句:

EstimatedTime.where(user_id: User.current.id, plan_on: date).pluck(:hours).sum

它将使用数据库数据来计算总和,绕过不一致的缓存问题。

相关内容

  • 没有找到相关文章

最新更新