lib/loaders/loader_base.rb in datashift-0.0.2 vs lib/loaders/loader_base.rb in datashift-0.1.0
- old
+ new
@@ -79,22 +79,27 @@
def self.multi_assoc_delim
@multi_assoc_delim ||= '|'
@multi_assoc_delim
end
-
+
def self.set_multi_assoc_delim(x) @multi_assoc_delim = x; end
+
# Options
# :instance_methods => true
def initialize(object_class, object = nil, options = {})
@load_object_class = object_class
- # Gather list of all possible 'setter' methods on AR class (instance variables and associations)
- DataShift::MethodMapper.find_operators( @load_object_class, :reload => true, :instance_methods => options[:instance_methods] )
+ # Gather names of all possible 'setter' methods on AR class (instance variables and associations)
+ DataShift::MethodDictionary.find_operators( @load_object_class, :reload => true, :instance_methods => options[:instance_methods] )
+ # Create dictionary of data on all possible 'setter' methods which can be used to
+ # populate or integrate an object of type @load_object_class
+ DataShift::MethodDictionary.build_method_details(@load_object_class)
+
@method_mapper = DataShift::MethodMapper.new
@options = options.clone
@headers = []
@default_data_objects ||= {}
@@ -113,19 +118,22 @@
def perform_load( input, options = {} )
raise "WARNING- ABSTRACT METHOD CALLED - Please implement perform_load()"
end
- # Core API - Given a list of free text column names from a file, map all headers to
- # method mapper's operator list.
+ # Core API - Given a list of free text column names from a file,
+ # map all headers to a method detail containing operator details.
+ #
+ # This is then available through @method_mapper.method_details.each
+ #
# Options:
# strict : report any header values that can't be mapped as an error
#
def map_headers_to_operators( headers, strict, mandatory = [])
@headers = headers
- @method_mapper.populate_methods( load_object_class, @headers )
+ method_details = @method_mapper.map_inbound_to_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, "Missing mappings for columns : #{@method_mapper.missing_methods.join(",")}" if(strict)
end
@@ -135,16 +143,16 @@
raise MissingMandatoryError, "Mandatory columns missing - please fix and retry."
end unless(mandatory.empty?)
end
- # Core API - Given a free text column name from a file, search method mapper for
+ # Core API - Given a single free text column name from a file, search method mapper for
# associated operator on base object class.
#
# If suitable association found, process row data and then assign to current load_object
def find_and_process(column_name, data)
- method_detail = MethodMapper.find_method_detail( load_object_class, column_name )
+ method_detail = MethodDictionary.find_method_detail( load_object_class, column_name )
if(method_detail)
prepare_data(method_detail, data)
process()
else
@@ -240,36 +248,45 @@
# has_and_belongs_to associations which require the load_object has an id for the join table
save_if_new
# A single column can contain multiple associations delimited by special char
+ # Size:large|Colour:red,green,blue => ['Size:large', 'Colour:red,green,blue']
columns = @current_value.to_s.split( LoaderBase::multi_assoc_delim)
# Size:large|Colour:red,green,blue => generates find_by_size( 'large' ) and find_all_by_colour( ['red','green','blue'] )
- columns.each do |assoc|
- operator, values = assoc.split(LoaderBase::name_value_delim)
+ columns.each do |col_str|
+
+ find_operator, col_values = "",""
+
+ if(@current_method_detail.find_by_operator)
+ find_operator, col_values = @current_method_detail.find_by_operator, col_str
+ else
+ find_operator, col_values = col_str.split(LoaderBase::name_value_delim)
+ raise "No key to find #{@current_method_detail.operator} in DB. Expected format key:value" unless(col_values)
+ end
+
+ find_by_values = col_values.split(LoaderBase::multi_value_delim)
- lookups = values.split(LoaderBase::multi_value_delim)
+ if(find_by_values.size > 1)
- if(lookups.size > 1)
+ @current_value = @current_method_detail.operator_class.send("find_all_by_#{find_operator}", find_by_values )
- @current_value = @current_method_detail.operator_class.send("find_all_by_#{operator}", lookups )
-
- unless(lookups.size == @current_value.size)
- found = @current_value.collect {|f| f.send(operator) }
- @load_object.errors.add( method_detail.operator, "Association with key(s) #{(lookups - found).inspect} NOT found")
+ unless(find_by_values.size == @current_value.size)
+ found = @current_value.collect {|f| f.send(find_operator) }
+ @load_object.errors.add( @current_method_detail.operator, "Association with key(s) #{(find_by_values - found).inspect} NOT found")
puts "WARNING: Association with key(s) #{(lookups - found).inspect} NOT found - Not added."
next if(@current_value.empty?)
end
else
- @current_value = @current_method_detail.operator_class.send("find_by_#{operator}", lookups )
+ @current_value = @current_method_detail.operator_class.send("find_by_#{find_operator}", find_by_values )
unless(@current_value)
- @load_object.errors.add( @current_method_detail.operator, "Association with key #{lookups} NOT found")
- puts "WARNING: Association with key #{lookups} NOT found - Not added."
+ @load_object.errors.add( @current_method_detail.operator, "Association with key #{find_by_values} NOT found")
+ puts "WARNING: Association with key #{find_by_values} NOT found - Not added."
next
end
end
\ No newline at end of file