根据Rails文档here和here,使用update_all
不会执行以下操作 -
updated_at
字段:limit
和:order
方法我正在尝试浏览我的代码库并删除update_all
的实例,特别是因为第一点。
有没有办法继续update_all
的方便并仍然运行验证?我知道我可以循环遍历每条记录并保存它,但这不仅在视觉上更混乱,而且效率也更低,因为它执行N个SQL语句而不是1
# before
User.where(status: "active").update_all(status: "inactive")
# after
User.where(status: "active").each { |u| u.update(status: "inactive") }
谢谢!
编辑:我正在使用Rails 4.2
答案 0 :(得分:12)
不幸的是update_all
更快,因为它没有为每条记录实例化一个活动记录对象,而是直接处理数据库。在您的情况下,由于您需要验证和回调,您需要实例化对象,因此您最好的选择是批量迭代1000并执行最初显示的更新。如:
User.where(status: "active").find_each { |u| u.update(status: "inactive") }
find_each
方法一次只加载1000个对象,因此不会使垃圾收集器超载。如果您有数十万行的批量记录,我会考虑返回update_all或将更新移至后台任务,因为它在部署时很容易导致超时。