Class: Miscellany::BatchingCsvProcessor
- Inherits:
-
Object
- Object
- Miscellany::BatchingCsvProcessor
- Defined in:
- lib/miscellany/batching_csv_processor.rb
Defined Under Namespace
Classes: RowError
Instance Attribute Summary collapse
-
#csv ⇒ Object
Returns the value of attribute csv.
-
#file_name ⇒ Object
Returns the value of attribute file_name.
Class Method Summary collapse
Instance Method Summary collapse
- #apply_row_to_model(_row, _instance) ⇒ Object
- #batch_rows_to_models(rows) ⇒ Object
- #build_model_from_row(row) ⇒ Object
- #find_or_init(_row) ⇒ Object
- #get_row_errors(row) ⇒ Object
-
#initialize(csv, file_name: nil) ⇒ BatchingCsvProcessor
constructor
A new instance of BatchingCsvProcessor.
- #log_line_error(message, line_number, **kwargs) ⇒ Object
- #map_defined_columns(row, map) ⇒ Object
- #process_in_batches(&blk) ⇒ Object
- #validate_line(row) ⇒ Object
Constructor Details
#initialize(csv, file_name: nil) ⇒ BatchingCsvProcessor
Returns a new instance of BatchingCsvProcessor.
9 10 11 12 |
# File 'lib/miscellany/batching_csv_processor.rb', line 9 def initialize(csv, file_name: nil) @csv = csv @file_name = file_name end |
Instance Attribute Details
#csv ⇒ Object
Returns the value of attribute csv.
5 6 7 |
# File 'lib/miscellany/batching_csv_processor.rb', line 5 def csv @csv end |
#file_name ⇒ Object
Returns the value of attribute file_name.
5 6 7 |
# File 'lib/miscellany/batching_csv_processor.rb', line 5 def file_name @file_name end |
Class Method Details
.file_matches?(file) ⇒ Boolean
78 79 80 81 82 |
# File 'lib/miscellany/batching_csv_processor.rb', line 78 def self.file_matches?(file) header = file.readline.strip.split(',') file.try(:rewind) headers_match?(header) end |
.headers_match?(headers) ⇒ Boolean
84 85 86 |
# File 'lib/miscellany/batching_csv_processor.rb', line 84 def self.headers_match?(headers) (self::HEADERS - headers).empty? end |
Instance Method Details
#apply_row_to_model(_row, _instance) ⇒ Object
31 32 33 |
# File 'lib/miscellany/batching_csv_processor.rb', line 31 def apply_row_to_model(_row, _instance) raise NotImplementedError end |
#batch_rows_to_models(rows) ⇒ Object
49 50 51 |
# File 'lib/miscellany/batching_csv_processor.rb', line 49 def batch_rows_to_models(rows) rows.map { |row| build_model_from_row(row) }.reject { |inst| inst.nil? || !inst.changed? } end |
#build_model_from_row(row) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/miscellany/batching_csv_processor.rb', line 53 def build_model_from_row(row) model = find_or_init(row) apply_row_to_model(row, model) return nil if model.respond_to?(:discarded_at) && model.discarded_at.present? && !model.persisted? model rescue ActiveRecord::RecordNotFound, RowError => err log_line_error(err., row[:line_number], exception: err) nil rescue StandardError => err log_line_error('An Internal Error Occurred', row[:line_number], exception: err) Raven.capture_exception(err) if defined?(Raven) nil end |
#find_or_init(_row) ⇒ Object
27 28 29 |
# File 'lib/miscellany/batching_csv_processor.rb', line 27 def find_or_init(_row) raise NotImplementedError end |
#get_row_errors(row) ⇒ Object
25 |
# File 'lib/miscellany/batching_csv_processor.rb', line 25 def get_row_errors(row); end |
#log_line_error(message, line_number, **kwargs) ⇒ Object
35 36 37 |
# File 'lib/miscellany/batching_csv_processor.rb', line 35 def log_line_error(, line_number, **kwargs) raise NotImplementedError end |
#map_defined_columns(row, map) ⇒ Object
68 69 70 71 72 73 74 75 76 |
# File 'lib/miscellany/batching_csv_processor.rb', line 68 def map_defined_columns(row, map) newh = {} map.each do |newk, oldk| next unless row.include?(oldk) newh[newk] = row[oldk] end newh end |
#process_in_batches(&blk) ⇒ Object
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/miscellany/batching_csv_processor.rb', line 14 def process_in_batches(&blk) batch = BatchProcessor.new(&blk) CSV.new(csv, headers: true, header_converters: :symbol).each.with_index do |row, line| row[:line_number] = line + 1 next unless validate_line(row) batch << row end batch.flush end |
#validate_line(row) ⇒ Object
39 40 41 42 43 44 45 46 47 |
# File 'lib/miscellany/batching_csv_processor.rb', line 39 def validate_line(row) errors = get_row_errors(row) || [] if errors.present? log_line_error(errors[0], row[:line_number]) false else true end end |