2017-07-28 25 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'方法会在模型上运行所有的回调函数,但是如果你没有,也许你可以为你的数据库打低级驱动程序。 –

相关问题