Class: CSVImporter::Row

Inherits:
Object
  • Object
show all
Defined in:
lib/csv_importer/row.rb

Overview

A Row from the CSV file.

Using the header, the model_klass and the identifier it builds the model to be persisted.

Instance Method Summary collapse

Instance Method Details

#build_modelObject



101
102
103
# File 'lib/csv_importer/row.rb', line 101

def build_model
  model_klass.new
end

#csv_attributesObject

A hash with this row’s attributes



29
30
31
# File 'lib/csv_importer/row.rb', line 29

def csv_attributes
  @csv_attributes ||= Hash[header.column_names.zip(row_array)]
end

#errorsObject

Error from the model mapped back to the CSV header if we can



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/csv_importer/row.rb', line 74

def errors
  Hash[
    model.errors.map do |attribute, errors|
      if column_name = header.column_name_for_model_attribute(attribute)
        [column_name, errors]
      else
        [attribute, errors]
      end
    end
  ]
end

#find_modelObject



90
91
92
93
94
95
96
97
98
99
# File 'lib/csv_importer/row.rb', line 90

def find_model
  return nil if identifiers.empty?

  model = build_model
  set_attributes(model)
  query = Hash[
    identifiers.map { |identifier| [ identifier, model.public_send(identifier) ] }
  ]
  model_klass.find_by(query)
end

#find_or_build_modelObject



86
87
88
# File 'lib/csv_importer/row.rb', line 86

def find_or_build_model
  find_model || build_model
end

#modelObject

The model to be persisted



17
18
19
20
21
22
23
24
25
26
# File 'lib/csv_importer/row.rb', line 17

def model
  @model ||= begin
    model = find_or_build_model

    set_attributes(model)

    after_build_blocks.each { |block| instance_exec(model, &block) }
    model
  end
end

#set_attribute(model, column_definition, csv_value) ⇒ Object

Set the attribute using the column_definition and the csv_value



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/csv_importer/row.rb', line 53

def set_attribute(model, column_definition, csv_value)
  if column_definition.to && column_definition.to.is_a?(Proc)
    to_proc = column_definition.to

    case to_proc.arity
    when 1 # to: ->(email) { email.downcase }
      model.public_send("#{column_definition.name}=", to_proc.call(csv_value))
    when 2 # to: ->(published, post) { post.published_at = Time.now if published == "true" }
      to_proc.call(csv_value, model)
    else
      raise ArgumentError, "`to` proc can only have 1 or 2 arguments"
    end
  else
    attribute = column_definition.attribute
    model.public_send("#{attribute}=", csv_value)
  end

  model
end

#set_attributes(model) ⇒ Object

Set attributes



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/csv_importer/row.rb', line 34

def set_attributes(model)
  header.columns.each do |column|
    value = csv_attributes[column.name]
    begin
      value = value.dup if value
    rescue TypeError
      # can't dup Symbols, Integer etc...
    end

    column_definition = column.definition
    next if column_definition.nil?

    set_attribute(model, column_definition, value)
  end

  model
end

#skip!Object



105
106
107
# File 'lib/csv_importer/row.rb', line 105

def skip!
  self.skip = true
end