如何在Ruby on Rails中创建批量操作事务

时间:2016-05-18 06:25:08

标签: ruby-on-rails ruby

以下功能正常工作但是如果任何记录包含非UTF-8字符,则会出现500错误。

我可以在此处使用事务进行批量操作,以便保存所有记录或者不保存所有记录吗?

我已尝试使用stackoverflow上提到的各种编码修复问题,但这不起作用。

def convert_save(model_name, csv_data, field_name=nil)
      target_model = model_name.classify.constantize
      csv_file = csv_data.read
      row_headers={}
      counter=0;
      all_recs=[];
      #Thread.new do
                CSV.parse(csv_file) do |row| 
                    if counter==0
                        temp=row
                        row_headers = Hash[temp.map.with_index.to_a]
                        counter +=1
                        next
                    end
                        #start fetch row and put into active record object
                        unless row[row_headers["name"]].nil?
                            temp={}
                            temp_time={}
                            for name in [:business_type_id, :user_id, :name, :country_id, :latitude, :longitude, :free_shipping]
                                temp[name] = row[row_headers[name.to_s]]
                            end
                            for name in [:homepage, :telephone, :email, :address, :facebook, :twitter, :google, :instagram, :pinterest, :ship_details]
                                temp[name] = row[row_headers[name.to_s]] ||= ""
                            end
                            for name in [:category_ids, :style_ids, :filter_ids, :shipping_country_ids]
                                temp[name] = row[row_headers[name.to_s]].try(:split, ",") unless row_headers[name.to_s].nil?
                            end
                            for name in [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday, :public_holiday]
                                temp_time[name.to_s] = row[row_headers[name.to_s]]  ||= ""
                            end
                            temp_time["appointment_only"] = row[row_headers["appointment_only"]]
                            temp["business_timing_attributes"] = temp_time
                            all_recs.push(temp)
                        end 
                end
                Business.create(all_recs)
                ActiveRecord::Base.connection.close
      end
    #end
  end   

1 个答案:

答案 0 :(得分:1)

您可以将create方法包装在事务中。如果任何INSERT失败,整个操作将被回滚:

Business.transaction do
  Business.create!(all_recs)
end

请注意,为了回滚事务,必须在查询后发生ActiveRecord错误。因此,您必须在此处使用create!而不是create来确保针对无效数据引发异常。