2016-12-07 401 views
2

我目前正在一個小項目上工作,我希望更快地播種我的數據庫。我將一個名爲「grand_total_points」的新列移植到我的用戶表中。所以最初我使用這個代碼。如何使用update_all但每個?有更好的方法嗎?

user = User.all 
user.each do |x| 
    x.grand_total_points = x.total_points 
    x.save! 
end 

這需要我很長時間,因爲我必須更新一百萬條記錄。 Total_points已經在我的用戶模型中定義,它計算所有已提交的用戶點數。原諒我的解釋。有沒有辦法使用update_all方法,但每個方法都包含在內?

回答

2

是的,可能的:

User.update_all('grand_total_points = total_points') 

它將生成以下SQL查詢:

UPDATE "users" SET "grand_total_points" = 'total_points' 

如果total_points不是列,但一個實例方法中,將邏輯到update_all查詢。

User.update_all("grand_total_points = #{total_points calculation translated into SQL terms}") 
+0

'total_points'對於每個用戶都是不同的,只有'total_points'對所有用戶都是相同的,你纔可以使用它。 – Thanh

+0

@ThanhHuynh這是一個錯字,在'total_points'(':total_points'')前應該有一個冒號 –

+0

我試過了,它不起作用。這段代碼會將所有用戶的'grand_total_points'列更新爲'total_points'字符串。 – Thanh

0

我發現了一些可以工作的東西。所以基本上,我將ruby代碼與執行SQL語句結合起來,然後將其放入遷移文件中。代碼如何工作。我希望這有幫助。確保你按照你的數據進行查詢。

class ChangeStuff < ActiveRecord::Migration 
    def change 
    points = Point.select('user_id, SUM(value) AS value').group(:user_id) 
    points.each do |point| 
    execute "UPDATE users SET grand_total_points = #{point.value} WHERE users.id = #{point.user_id}" 
    end 
    end 
end 

您應該在此之後運行bundle exec rake db:migrate。正常的方式需要2-3小時。這隻花了我2分鐘。

相關問題