Module: SmartCsvImport::Processor::RowProcessor

Defined in:
lib/smart_csv_import/processor/row_processor.rb

Defined Under Namespace

Classes: ChunkResult

Class Method Summary collapse

Class Method Details

.blank_row?(row) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/smart_csv_import/processor/row_processor.rb', line 47

def blank_row?(row)
  row.except(:csv_line_number).values.all? { |v| v.nil? || v.to_s.empty? }
end

.build_attributes(csv_row, field_map) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/smart_csv_import/processor/row_processor.rb', line 51

def build_attributes(csv_row, field_map)
  field_map.each_with_object({}) do |(header, field_name), attrs|
    next if header == :csv_line_number

    attrs[field_name] = csv_row[header]
  end
end

.collect_row_errors(form, row_number) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'lib/smart_csv_import/processor/row_processor.rb', line 59

def collect_row_errors(form, row_number)
  form.errors.group_by_attribute.each_with_object([]) do |(attr, row_errors), errs|
    errs << RowError.new(
      row: row_number,
      column: attr.to_sym,
      messages: row_errors.map(&:message)
    )
  end
end

.process_chunk(chunk, field_map:, form_class:, dry_run:) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/smart_csv_import/processor/row_processor.rb', line 10

def process_chunk(chunk, field_map:, form_class:, dry_run:)
  blank_rows, data_rows = chunk.partition { |row| blank_row?(row) }
  imported = 0
  failed = 0
  errors = []
  aborted_error = nil

  data_rows.each do |csv_row|
    outcome = submit_row(csv_row, field_map: field_map, form_class: form_class, dry_run: dry_run)
    case outcome.first
    when :imported
      imported += 1
    when :failed
      failed += 1
      errors = [*errors, *outcome.last]
    when :aborted
      aborted_error = outcome.last
      break
    end
  end

  ChunkResult.new(
    imported: imported, failed: failed, blank: blank_rows.size,
    errors: errors, aborted_error: aborted_error
  )
end

.submit_row(csv_row, field_map:, form_class:, dry_run:) ⇒ Object



37
38
39
40
41
42
43
44
45
# File 'lib/smart_csv_import/processor/row_processor.rb', line 37

def submit_row(csv_row, field_map:, form_class:, dry_run:)
  form = form_class.new(build_attributes(csv_row, field_map))
  success = dry_run ? form.valid? : form.save
  return [:imported] if success

  [:failed, collect_row_errors(form, csv_row[:csv_line_number] || 0)]
rescue ActiveRecord::StatementInvalid => e
  [:aborted, e]
end