保存活动记录数组

时间:2010-02-18 22:45:46

标签: ruby-on-rails ruby

我有一个像这样的数组

a = []

a << B.new(:name => "c")
a << B.new(:name => "s")
a << B.new(:name => "e")
a << B.new(:name => "t")

我怎样才能立刻保存它?

6 个答案:

答案 0 :(得分:45)

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

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

您可以在Rails和Ruby API中阅读ActiveRecord Transactionsthe each method

答案 1 :(得分:25)

a.each(&:save)

这会在数组中的每个项目上调用B#save

答案 2 :(得分:11)

所以我认为我们需要一个中间立场,让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

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

答案 3 :(得分:2)

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

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

if broken.present?
  # error message
end

答案 4 :(得分:0)

在事务中包装save是不够的:如果未通过验证,则不会引发异常并且不会触发回滚。

我可以建议:

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

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

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


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

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

答案 5 :(得分:0)

如果您正在寻找比保存循环中每一行更有效的解决方案,请在此处查看我的答案Ruby on Rails - Import Data from a CSV file

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