Class: CsvRowModel::Import::File

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks
Includes:
ActiveWarnings
Defined in:
lib/csv_row_model/public/import/file.rb

Overview

Represents a csv file and handles parsing to return Import

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_path, row_model_class, context = {}) ⇒ File

Returns a new instance of File

Parameters:

  • file_path (String)

    path of csv file

  • row_model_class (Import)

    model class returned for importing

  • context (Hash) (defaults to: {})

    context passed to the CsvRowModel::Import


28
29
30
31
32
33
# File 'lib/csv_row_model/public/import/file.rb', line 28

def initialize(file_path, row_model_class, context={})
  @csv = Csv.new(file_path)
  @row_model_class = row_model_class
  @context = context.to_h.symbolize_keys
  reset
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context


12
13
14
# File 'lib/csv_row_model/public/import/file.rb', line 12

def context
  @context
end

#csvObject (readonly)

Returns the value of attribute csv


10
11
12
# File 'lib/csv_row_model/public/import/file.rb', line 10

def csv
  @csv
end

#current_row_modelObject (readonly)

Returns the value of attribute current_row_model


12
13
14
# File 'lib/csv_row_model/public/import/file.rb', line 12

def current_row_model
  @current_row_model
end

#indexObject (readonly)

-1 = start of file, 0 to infinity = index of row_model, nil = end of file, no row_model


11
12
13
# File 'lib/csv_row_model/public/import/file.rb', line 11

def index
  @index
end

#previous_row_modelObject (readonly)

Returns the value of attribute previous_row_model


12
13
14
# File 'lib/csv_row_model/public/import/file.rb', line 12

def previous_row_model
  @previous_row_model
end

#row_model_classObject (readonly)

Returns the value of attribute row_model_class


10
11
12
# File 'lib/csv_row_model/public/import/file.rb', line 10

def row_model_class
  @row_model_class
end

Instance Method Details

#_abort?Boolean (protected)

Returns:


89
90
91
92
93
# File 'lib/csv_row_model/public/import/file.rb', line 89

def _abort?
  abort = abort?
  run_callbacks(:abort) if abort
  abort
end

#_skip?Boolean (protected)

Returns:


95
96
97
98
99
# File 'lib/csv_row_model/public/import/file.rb', line 95

def _skip?
  skip = skip?
  run_callbacks(:skip) if skip
  skip
end

#abort?Boolean

Returns true, if the file should abort reading

Returns:

  • (Boolean)

    returns true, if the file should abort reading


79
80
81
# File 'lib/csv_row_model/public/import/file.rb', line 79

def abort?
  !valid? || !!current_row_model.try(:abort?)
end

#each(context = {}) ⇒ Object

Iterates through the entire csv file and provides the current_row_model in a block, while handing aborts and skips via. calling Model#abort? and Model#skip?


64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/csv_row_model/public/import/file.rb', line 64

def each(context={})
  return to_enum(__callee__) unless block_given?
  return false if _abort?

  while self.next(context)
    run_callbacks :each_iteration do
      return false if _abort?
      next if _skip?

      yield current_row_model
    end
  end
end

#headersObject


35
36
37
38
# File 'lib/csv_row_model/public/import/file.rb', line 35

def headers
  h = csv.headers
  h.class == Array ? h : []
end

#headers_countObject (protected)


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/csv_row_model/public/import/file.rb', line 108

def headers_count
  return if headers_invalid_row || !csv.valid?
  return if row_model_class.try(:row_names) # FileModel check

  size_until_blank = ((headers || []).map { |h| h.try(:strip) }.rindex(&:present?) || -1) + 1
  column_names = row_model_class.column_names

  if row_model_class.dynamic_columns?
    return if size_until_blank >= column_names.size
    expected_headers_size = ">=#{column_names.size}"
  else
    return if size_until_blank == column_names.size
    expected_headers_size = column_names.size
  end
  message = [
    "count does not match.",
    " Given headers (#{size_until_blank}).",
    " Expected headers (#{expected_headers_size}): #{column_names.join(", ")}"
  ]
  message << ", and unlimited #{row_model_class.dynamic_column_names.join(", ")}" if row_model_class.dynamic_columns?
  errors.add(:headers, message.join)
end

#headers_invalid_rowObject (protected)

Validations


104
105
106
# File 'lib/csv_row_model/public/import/file.rb', line 104

def headers_invalid_row
  errors.add(:csv, "has header with #{csv.headers.message}") if csv.headers.class < Exception
end

#next(context = {}) ⇒ Object

Gets the next row model based on the context


48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/csv_row_model/public/import/file.rb', line 48

def next(context={})
  return if end_of_file?

  run_callbacks :next do
    context = context.to_h.reverse_merge(self.context)
    @previous_row_model = current_row_model
    @index += 1
    @current_row_model = row_model_class.next(self, context)
    @current_row_model = @index = nil if end_of_file?
  end

  current_row_model
end

#resetObject

Resets the file back to the top


41
42
43
44
45
# File 'lib/csv_row_model/public/import/file.rb', line 41

def reset
  csv.reset
  @index = -1
  @current_row_model = nil
end

#skip?Boolean

Returns true, if the file should skip current_row_model

Returns:

  • (Boolean)

    returns true, if the file should skip current_row_model


84
85
86
# File 'lib/csv_row_model/public/import/file.rb', line 84

def skip?
  !!current_row_model.try(:skip?)
end