2017-07-28 55 views
0

我使用Rails 5.我有一個模型,看起來像這樣如何使用多個Rails保存方法創建事務?

class CryptoIndexCurrency < ApplicationRecord 
    belongs_to :crypto_currency 
end 

我有一個服務的方法,我想填充此表的記錄,這是我不喜歡這樣

CryptoIndexCurrency.delete_all 
currencies.each do |currency| 
    cindex_currency = CryptoIndexCurrency.new({:crypto_currency => currency}) 
    cindex_currency.save 
end 

問題是,上述不是很事務,只要在第一條語句後發生了什麼,「delete_all」將會執行,但沒有其他事情會發生。什麼是在這裏創建交易的正確方式,同樣重要,我在哪裏放置該代碼?想知道這裏的Rails約定。

回答

0

我認爲你可以這樣做:

CryptoIndexCurrency.transaction do 
    CryptoIndexCurrency.delete_all 
    CryptoIndexCurrency.create(currencies.map{ |c| {crypto_currency: c} }) 
end 
+0

你把這個文件放進哪個文件? – Dave

+0

無論你在做什麼事情,你都說「我有一種服務方式......我喜歡這樣做」。它會回滾錯誤,包括刪除,但我確實同意你應該確保你將要創建的記錄的有效性,但是你應該首先創建貨幣數組,以防止循環數組的兩倍(一個用於驗證,一個用於映射)。 –

0

如果您正在使用ActiveRecord可以使用內建的交易機制。否則,一種方法是確保您驗證所有數據,並且只有在一切有效時才進行保存。看看validates_associate之類的。

也就是說,如果你的過程本質上是不可可驗證/不確定性(例如,你調用外部API來驗證的支付),那麼最好是要確保你有把你失敗的照顧一些清潔方法

如果你有確定性故障:

def new_currencies_valid?(currencies) 
    currencies.each do 
    return false if not currency.valid?(:create) 
    end 
    true 
end 

if new_currencies_valid?(new_currencies) 
    Currency.delete_all # See note 
    new_currencies.each(&:save) 
end 

阿里納斯:除非你真的瞭解自己在做什麼,我建議叫destroy_all運行在刪除回調(如刪除dependent: :destroy)協會

+0

有兩件事 - 你把這段代碼放在哪個文件中,並且是兩行 - 「Currency.delete_all」和「new_currencies.each(&:save)」真的作爲一個原子單元運行? – Dave

+0

我不知道你的業務邏輯,所以我不能告訴你把文件放在哪裏,但是我想在服務對象中。 'new_currencies.each(&:save)'不能保證原子性。你想要做的事情並不清楚,你會從「交易」中得到什麼樣的行爲。通常交易是用來創建一個(或一組相關的)模型,但不是爲大規模播種而設計的。如果中途出現錯誤應該怎麼辦? 'save'方法會在模型上運行所有的回調函數,但是如果你沒有,也許你可以爲你的數據庫打低級驅動程序。 –

相關問題