From ea02391091f22547ce22b33d8707c5f629451b39 Mon Sep 17 00:00:00 2001 From: Jordan Owens Date: Mon, 4 Apr 2016 11:55:59 -0400 Subject: [PATCH] Refactor code for validating models on import --- lib/activerecord-import/import.rb | 43 +++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/activerecord-import/import.rb b/lib/activerecord-import/import.rb index bd6be4aa..ffd5b786 100644 --- a/lib/activerecord-import/import.rb +++ b/lib/activerecord-import/import.rb @@ -387,7 +387,19 @@ def import_helper( *args ) end return_obj = if is_validating - import_with_validations( column_names, array_of_attributes, options ) + if models + import_with_validations( column_names, array_of_attributes, options ) do |failed| + models.each_with_index do |model, i| + model = model.dup if options[:recursive] + next if model.valid?(options[:validate_with_context]) + model.send(:raise_record_invalid) if options[:raise_error] + array_of_attributes[i] = nil + failed << model + end + end + else + import_with_validations( column_names, array_of_attributes, options ) + end else (num_inserts, ids) = import_without_validations_or_callbacks( column_names, array_of_attributes, options ) ActiveRecord::Import::Result.new([], num_inserts, ids) @@ -424,21 +436,26 @@ def import_from_table( options ) # :nodoc: def import_with_validations( column_names, array_of_attributes, options = {} ) failed_instances = [] - # create instances for each of our column/value sets - arr = validations_array_for_column_names_and_attributes( column_names, array_of_attributes ) + if block_given? + yield failed_instances + else + # create instances for each of our column/value sets + arr = validations_array_for_column_names_and_attributes( column_names, array_of_attributes ) + + # keep track of the instance and the position it is currently at. if this fails + # validation we'll use the index to remove it from the array_of_attributes + arr.each_with_index do |hsh, i| + instance = new do |model| + hsh.each_pair { |k, v| model[k] = v } + end - # keep track of the instance and the position it is currently at. if this fails - # validation we'll use the index to remove it from the array_of_attributes - arr.each_with_index do |hsh, i| - instance = new do |model| - hsh.each_pair { |k, v| model[k] = v } + next if instance.valid?(options[:validate_with_context]) + raise(ActiveRecord::RecordInvalid, instance) if options[:raise_error] + array_of_attributes[i] = nil + failed_instances << instance end - - next if instance.valid?(options[:validate_with_context]) - raise(ActiveRecord::RecordInvalid, instance) if options[:raise_error] - array_of_attributes[i] = nil - failed_instances << instance end + array_of_attributes.compact! num_inserts, ids = if array_of_attributes.empty? || options[:all_or_none] && failed_instances.any?