保存活动记录数组

我有这样的数组

a = [] a < "c") a < "s") a < "e") a < "t") 

我怎么能立刻保存它?

 a.each(&:save) 

这将在arrays中的每个项目上调用B#save

 B.transaction do a.each(&:save!) end 

这将创建一个循环遍历数组的每个元素并在其上调用element.save的事务。

您可以阅读有关ActiveRecord事务以及Rails和Ruby API中的每个方法的信息。

所以我认为我们需要一个中间立场,让Alexey提高例外并中止交易和Jordan的单线解决方案。 我可以建议:

 B.transaction do success = a.map(&:save) unless success.all? errored = a.select{|b| !b.errors.blank?} # do something with the errored values raise ActiveRecord::Rollback end end 

这将为您提供两个方面:具有回滚的事务,知道哪些记录失败,甚至可以让您访问其中的validation错误。

我知道这是一个古老的问题,但我很惊讶没有人想到这个:

 B.transaction do broken = a.reject { |o| o.save } raise ActiveRecord::Rollback if broken.present? end if broken.present? # error message end 

在事务中包装save是不够的:如果未传递validation,则不会引发exception并且不会触发回滚。

我可以建议一下:

 B.transaction do a.each do |o| raise ActiveRecord::Rollback unless o.save end end 

只做B.transaction do a.each(&:save!) end也不是一个选项,因为事务块不会拯救除ActiveRecord::Rollback之外的任何exception,并且应用程序在validation失败时会崩溃。

如果记录已保存,我不知道如何检查。


更新 。 由于有人低估了我的答案,我认为这个人正在寻找一个剪切和粘贴的解决方案:),所以这里有一些(丑陋的:))处理失败/成功价值的方法:

 save_failed = nil B.transaction do a.each do |o| unless o.save save_failed = true raise ActiveRecord::Rollback end end end if save_failed # ... else # ... end 

如果您正在寻找比保存循环中每一行更有效的解决方案,请在此处查看我的答案Ruby on Rails – 从CSV文件导入数据

我建议在那里使用gem activerecord-import