Reputation: 73
Suppose I have a excel sheet that contains data to be stored in the db.I used roo gem and inserted the data from excel sheet successfully.Now I am trying to validate. Assume my excel sheet as:
s.no name age
1 abc 12
2 def qwer
3 asd 23
when I upload this sheet, the 2 row data is roll-backed and 1,3 row data is stored in db. What I am trying to do is if rollback operation occurs then the remaining records should not be stored in db.i.e the row 3 data should not be stored as row 2 is roll-backed.Any help is appreciated.Thanks.
An update: Here is my code in controller:
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
I want to roll-back entire excel sheet not only records..Is there any way to do so?
Upvotes: 1
Views: 256
Reputation: 23671
You can break the loop if any record is not valid that will not save further records
Something like
CSV.foreach("file.csv", headers: true) do |row|
user = User.new(name: row['name'], age: row['age'])
break unless user.valid?
user.save
end
EDIT:
Taking help from @Rais suggestion you can do somthing like this
User.transaction do
CSV.foreach("file.csv", headers: true) do |row|
User.create!(name: row['name'], age: row['age'])
end
end
Upvotes: 1
Reputation: 69
Just to add,you can achieve atomicity using ActiveRecord Transactions
Quoting from rails api documentation-
Transactions are protective blocks where SQL statements are only permanent if they can all succeed as one atomic action. The classic example is a transfer between two accounts where you can only have a deposit if the withdrawal succeeded and vice versa. Transactions enforce the integrity of the database and guard the data against program errors or database break-downs. So basically you should use transaction blocks whenever you have a number of statements that must be executed together or not at all.
For example:
ActiveRecord::Base.transaction do
david.withdrawal(100)
mary.deposit(100)
end
This example will only take money from David and give it to Mary if neither withdrawal nor deposit raise an exception. Exceptions will force a ROLLBACK that returns the database to the state before the transaction began. Be aware, though, that the objects will not have their instance data returned to their pre-transactional state.
Upvotes: 0