2013-12-19 56 views
2

我有一個Subscription模型,其中price字段,我的最後一次遷移引入了一個名爲per_month_price的字段。我正在尋找一種可以比簡單的.each {...}更快地更新記錄的方法。例如:Rails根據字段值更新幾條記錄

Subscription.update_all {|c| c.per_month_price = c.price/12}

+1

我的不好,我收回了我的近距離投票。 @MarekLipka感謝您指出。 –

+1

你可以將它包裝在一個事務中以節省一些預處理和後處理的週期(創建索引等)。但是我認爲性能不應該太關鍵,因爲它是一次運行的代碼。 –

回答

5

工作,爲什麼不乾脆用

Subscription.update_all("per_month_price = price/12") 

這是工作。它採用聲明並運行所有找到的記錄。 這在軌道上很常見。

http://apidock.com/rails/ActiveRecord/Relation/update_all

downvote前,請檢查!

+0

就像http://apidock.com/rails/ActiveRecord/Relation/update_all中所述。沒有必要從外部獲取參數。所以它運行的sql語句將價格/ 12填入per_month_price。 – devanand

0

也許我失去了一些東西,但爲什麼它添加到在所有如果可以通過編程從現有的列來確定它的數據庫?只要創建一個虛擬屬性:

class Subscription < ActiveRecord::Base 

    . 
    . 
    . 

    def per_month_price 
    self.price/12 
    end 

    def per_month_price=(arg) 
    self.price = arg*12 
    end 

end 

,如果你有在你的DB一個per_month_price列這將功能相同。它將更加高效,因爲您不必非常多地訪問數據庫,並且它消除了列(priceper_month_price)在某個地方會變得與彼此不一致的(非常可能)的可能性。如果你更新一個,但忘記更新另一個。

對不起,我沒有直接回答你的問題(特別是通過谷歌來到這裏的任何人),但這對我來說似乎是一個更好的設計。

1

您可以嘗試在原始sql中執行此操作。我不知道的是,語法是標準的SQL,它可能不會與所有的DB

ActiveRecord::Base.connection.execute('UPDATE Subscription SET per_month_price = price/12') 

它似乎確定與mySQL