Creating web applications in rails.Therefore, we are currently implementing the csv file capture function.I was able to import csv, but I would like to use transactions to import csv files.(If an error occurs, I would like to cancel all changes and return to the original screen to display the error.) However, I did not know how to implement it, so I asked you a question.
$rails-v
5.0.0
controller/costs_controller.rb
def import
if params[:csv_file].blank?
redirect_to action: 'index', error: 'Please select CSV to load'
elsif File.extname(params[:csv_file].original_filename)!=".csv"
redirect_to action: 'index', notice: 'Only csv files can be loaded'
else
num = Cost.import_by_csv (params[:csv_file])
redirect_to action: 'index', notice: "# {num.to_s} data information added/updated"
end
end
model/cost.rb
require'csv'
class Cost<ActiveRecord::Base
# Register the contents of the csv file in DB
def self.import_by_csv(file)
imported_num = 0
open(file.path, 'r:cp932:utf-8', undef::replace) do | f |
csv=CSV.new(f, :headers=>:first_row)
caches = Cost.all.index_by (&:code)
csv.each do | row |
next if row.header_row?
# Convert CSV Row Information to HASH
table = Hash [[row.headers, row.fields].transpose]
# Registered Data Information
# Create if not registered
cost=caches [table['code']]
if cost.nil?
cost=new
end
# data information update
cost.attributes=table.slice(*table.except(:created_at,:updated_at).keys)
# Save for validation ok
if cost.valid?
cost.save!
imported_num+=1
end
end
end
# return the number of updates
imported_num
end
end
views/costs/index.html.slim
=form_tag import_costs_path, method::post, multipart:true do
= file_field_tag —csv_file
= submit_tag 'CSV Read'
route.rb
Rails.application.routes.drawdo
resources —costs do
post:import, on::collection
end
That's all the current code.When I looked into the transaction, I found out that
Cost.transaction do
------ Code -----
end
There is a transaction implementation as shown in , but I don't know where and how to write it...
I apologize for the inconvenience, but I would appreciate it if you could let me know.
Thank you for your cooperation.
A transaction summarizes a set of actions that you want to be consistent with.
In this case, csv.each
to end
should be included in Cost.transaction do
to end
.If there is an error in the middle (for example, validation failure) and you want to roll back, use raise ActiveRecord::Rollback
.
In addition, if a database-side constraint fails, an exception will occur, so please handle it properly.
© 2024 OneMinuteCode. All rights reserved.