【发布时间】:2020-01-07 11:02:26
【问题描述】:
我正在寻找获取 Rails 中查询集大小的最佳方法。但是,元素是循环更新的,我需要在更新之前计算元素的数量。这是一些示例(错误!)代码。
p = participations.where(invited_at: nil).limit(50)
p.each do |participation|
# Invite may raise an exception, but also contains operations that
# cannot be undone
participation.invite()
participation.invited_at = Time.zone.now
participation.save
end
DoStuff() if p.count > 0
此代码不起作用,因为p.count 处的调用创建了一个新的数据库查询,该查询不考虑循环中已更新的记录。因此,如果少于 50 条记录,则全部更新,不会调用 DoStuff()。
Rails 中最惯用的方式来处理这个问题:
- 将
if p.count部分移出循环,只有在有记录时才进入循环? - 将
p.count替换为p.size(如果我对size的理解正确,这不会引起任何额外的查询) - 计算循环中的迭代次数,然后使用该数字
我感觉 1 在 ruby 中最地道,但我对这门语言没有太多经验。
编辑:改进的示例更接近原始代码。
编辑:
问题不在于对循环中的参与者执行的更新查询。这些查询应该是单独的查询,以跟踪哪些参与已经被处理,即使出现错误。相反,问题是应该调用DoStuff(),只要在循环中处理了任何记录。但是,由于count 执行新查询AFTER记录已被处理,如果要处理的元素少于 50 个,则将全部更新并且不会调用 DoStuff()。 p>
【问题讨论】:
-
但是,因为 count 会在处理完记录后执行新的查询,...,所以使用
size,不是吗?p已经在内存中,如果没有改变它的值,那么 DoStuff 的使用应该不会受到影响。
标签: mysql ruby-on-rails ruby