2016-09-22 25 views
3

根據Rails的文檔herehere,使用update_all不執行以下操作 -當使用`運行驗證update_all`

  • 它將跳過驗證
  • 它不更新updated_at
  • 它默默地忽略了:limit:order方法

我正在嘗試通過我的代碼庫並刪除update_all的實例,特別是因爲第一點。

有沒有辦法仍然有update_all的便利,仍然運行驗證?我明白,我可以通過每個記錄循環,並保存它,而是因爲它執行ň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

你可能想看看[批次](http://api.rubyonrails.org/classes/ActiveRecord/Batches.html) –

回答

4

不幸update_all的方式更快,因爲它不會實例每條記錄都有一個活動記錄對象,而是直接與數據庫交易。在你的情況中,因爲你需要驗證和回調,所以你需要實例化對象,所以你最好的選擇是批量迭代1000次,並執行最初顯示的更新。如:

User.where(status: "active").find_each { |u| u.update(status: "inactive") } 

find_each方法一次只加載1000個對象因此不超載垃圾收集器。如果您在成千上萬行中擁有批量記錄,我會考慮回到update_all或將更新移動到後臺任務,因爲它在部署時很容易導致超時。