1

假设我有一个 excel 表,其中包含要存储在 db 中的数据。我使用 roo gem 并成功插入了 excel 表中的数据。现在我正在尝试验证。假设我的excel表为:

s.no  name    age
 1    abc     12
 2    def     qwer
 3    asd     23

当我上传这张表时,2 行数据被回滚,1,3 行数据存储在 db 中。我想要做的是,如果发生回滚操作,那么剩余的记录不应存储在 db 中。即第 3 行数据不应存储为第 2 行已回滚。感谢任何帮助。谢谢。

更新:这是我在控制器中的代码:

def  fetch_excel_data

ex = Roo::Excel.new("/desktop/abc.xls")
ex.default_sheet = ex.sheets[0]
2.upto(ex.last_row) do |line| 
    name = ex.cell(line,2)
    age = ex.cell(line,ex.last_column)
    byebug
    @product = Product.create(:name => name,:age => age)
     @product.save!
     flash[:success] = "data is stored successfully"
end
end

我想回滚整个 excel 表不仅记录..有什么办法吗?

4

2 回答 2

1

如果任何记录无效且不会保存更多记录,您可以中断循环

就像是

CSV.foreach("file.csv", headers: true) do |row|
  user = User.new(name: row['name'], age: row['age'])
  break unless user.valid?
  user.save
end

编辑:

从@Rais的建议中得到帮助,你可以做这样的事情

User.transaction do
  CSV.foreach("file.csv", headers: true) do |row|
    User.create!(name: row['name'], age: row['age'])
  end
end
于 2017-02-24T11:58:31.987 回答
0

补充一点,您可以使用ActiveRecord Transactions实现原子性

引用 rails api 文档-

事务是保护性块,其中 SQL 语句只有在它们都可以作为一个原子操作成功时才​​是永久的。典型的例子是两个账户之间的转账,如果取款成功,您只能进行存款,反之亦然。事务强制执行数据库的完整性并保护数据免受程序错误或数据库故障的影响。因此,基本上,只要您有许多必须一起执行或根本不执行的语句,您就应该使用事务块。

例如:

ActiveRecord::Base.transaction do
  david.withdrawal(100)
  mary.deposit(100)
end

这个例子只会在提款和存款都没有引发异常的情况下从大卫那里取钱并将其交给玛丽。异常将强制执行 ROLLBACK,将数据库返回到事务开始之前的状态。但请注意,对象不会将其实例数据返回到其事务前状态。

于 2017-02-24T12:19:50.353 回答