Class: ARLoader::CsvLoader

Inherits:
LoaderBase show all
Defined in:
lib/loaders/csv_loader.rb

Instance Attribute Summary

Attributes inherited from LoaderBase

#current_method_detail, #current_value, #failed_objects, #headers, #load_object, #load_object_class, #loaded_objects, #options

Instance Method Summary collapse

Methods inherited from LoaderBase

#abort_on_failure?, #contains_mandatory?, #failed_count, #find_and_process, #find_or_new, #loaded_count, #missing_mandatory, #new_load_object, #process, #reset, #save, set_multi_assoc_delim, set_multi_value_delim, set_name_value_delim

Constructor Details

#initialize(klass, object = nil, options = {}) ⇒ CsvLoader

Returns a new instance of CsvLoader.



17
18
19
20
# File 'lib/loaders/csv_loader.rb', line 17

def initialize(klass, object = nil, options = {})
  super( klass, object, options )
  raise "Cannot load - failed to create a #{klass}" unless @load_object
end

Instance Method Details

#load(file_name, options = {}) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/loaders/csv_loader.rb', line 23

def load(file_name, options = {})

  require "csv"

  # TODO - abstract out what a 'parsed file' is - so a common object can represent excel,csv etc
  # then  we can make load() more generic
  
  @parsed_file = CSV.read(file_name)


  @headers = @parsed_file.shift

  @method_mapper = ARLoader::MethodMapper.new

  # Convert the list of headers into suitable calls on the Active Record class
  @method_mapper.populate_methods( load_object_class, @headers )

  unless(@method_mapper.missing_methods.empty?)
    puts "WARNING: Following column headings could not be mapped : #{@method_mapper.missing_methods.inspect}"
    raise MappingDefinitionError, "ERROR: Missing mappings for #{@method_mapper.missing_methods.size} column headings"
  end

  #if(options[:verbose])
  puts "\n\n\nLoading from CSV file: #{file_name}"
  puts "Processing #{@parsed_file.size} rows"
  # end

  load_object_class.transaction do
    @loaded_objects =  []

    @parsed_file.each do |row|
  
      # TODO - Smart sorting of column processing order ....
      # Does not currently ensure mandatory columns (for valid?) processed first but model needs saving
      # before associations can be processed so user should ensure mandatory columns are prior to associations

      # as part of this we also attempt to save early, for example before assigning to
      # has_and_belongs_to associations which require the load_object has an id for the join table

      # Iterate over the columns method_mapper found in Excel,
      # pulling data out of associated column
      @method_mapper.method_details.each_with_index do |method_detail, col|

        value = row[col]

        process(method_detail, value)
      end

      # TODO - handle when it's not valid ?
      # Process rest and dump out an exception list of Products ??

      puts "SAVING ROW #{row} : #{load_object.inspect}" #if options[:verbose]

      save

      # don't forget to reset the object or we'll update rather than create
      new_load_object

    end
  end

end