lib/datashift/method_mapper.rb in datashift-0.1.0 vs lib/datashift/method_mapper.rb in datashift-0.2.1

- old
+ new

@@ -1,91 +1,91 @@ -# Copyright:: (c) Autotelik Media Ltd 2011 -# Author :: Tom Statter -# Date :: Aug 2010 -# License:: MIT -# -# Details:: A base class that stores details of all possible associations on AR classes and, -# given user supplied class and name, attempts to find correct attribute/association. -# -# Derived classes define where the user supplied list of names originates from. -# -# Example usage, load from a spreadsheet where the column names are only -# an approximation of the actual associations. Given a column heading of -# 'Product Properties' on class Product, find_method_detail() would search AR model, -# and return details of real has_many association 'product_properties'. -# -# This real association can then be used to send spreadsheet row data to the AR object. -# -require 'method_detail' -require 'method_dictionary' - -module DataShift - - class MethodMapper - - attr_accessor :header_row, :headers - attr_accessor :method_details, :missing_methods - - - # As well as just the column name, support embedding find operators for that column - # in the heading .. i.e Column header => 'BlogPosts:user_id' - # ... association has many BlogPosts selected via find_by_user_id - # - def self.column_delim - @column_delim ||= ':' - @column_delim - end - - def self.set_column_delim(x) @column_delim = x; end - - - def initialize - @method_details = [] - @headers = [] - end - - # Build complete picture of the methods whose names listed in method_list - # Handles method names as defined by a user or in file headers where names may - # not be exactly as required e.g handles capitalisation, white space, _ etc - # Returns: Array of matching method_details - # - def map_inbound_to_methods( klass, method_list ) - - @method_details, @missing_methods = [], [] - - method_list.each do |name| - x, lookup = name.split(MethodMapper::column_delim) - md = MethodDictionary::find_method_detail( klass, x ) - - # TODO be nice if we could cheeck that the assoc on klass responds to the specified - # lookup key now (nice n early) - # active_record_helper = "find_by_#{lookup}" - - md.find_by_operator = lookup if(lookup) # TODO and klass.x.respond_to?(active_record_helper)) - md ? @method_details << md : @missing_methods << x - end - #@method_details.compact! .. currently we may need to map via the index on @method_details so don't remove nils for now - @method_details - end - - # The raw client supplied names - def method_names() - @method_details.collect( &:name ) - end - - # The true operator names discovered from model - def operator_names() - @method_details.collect( &:operator ) - end - - # Returns true if discovered methods contain every operator in mandatory_list - def contains_mandatory?( mandatory_list ) - [ [*mandatory_list] - operator_names].flatten.empty? - end - - def missing_mandatory( mandatory_list ) - [ [*mandatory_list] - operator_names].flatten - end - - end - +# Copyright:: (c) Autotelik Media Ltd 2011 +# Author :: Tom Statter +# Date :: Aug 2010 +# License:: MIT +# +# Details:: A base class that stores details of all possible associations on AR classes and, +# given user supplied class and name, attempts to find correct attribute/association. +# +# Derived classes define where the user supplied list of names originates from. +# +# Example usage, load from a spreadsheet where the column names are only +# an approximation of the actual associations. Given a column heading of +# 'Product Properties' on class Product, find_method_detail() would search AR model, +# and return details of real has_many association 'product_properties'. +# +# This real association can then be used to send spreadsheet row data to the AR object. +# +require 'method_detail' +require 'method_dictionary' + +module DataShift + + class MethodMapper + + attr_accessor :header_row, :headers + attr_accessor :method_details, :missing_methods + + + # As well as just the column name, support embedding find operators for that column + # in the heading .. i.e Column header => 'BlogPosts:user_id' + # ... association has many BlogPosts selected via find_by_user_id + # + def self.column_delim + @column_delim ||= ':' + @column_delim + end + + def self.set_column_delim(x) @column_delim = x; end + + + def initialize + @method_details = [] + @headers = [] + end + + # Build complete picture of the methods whose names listed in method_list + # Handles method names as defined by a user or in file headers where names may + # not be exactly as required e.g handles capitalisation, white space, _ etc + # Returns: Array of matching method_details + # + def map_inbound_to_methods( klass, method_list ) + + @method_details, @missing_methods = [], [] + + method_list.each do |name| + x, lookup = name.split(MethodMapper::column_delim) + md = MethodDictionary::find_method_detail( klass, x ) + + # TODO be nice if we could cheeck that the assoc on klass responds to the specified + # lookup key now (nice n early) + # active_record_helper = "find_by_#{lookup}" + + md.find_by_operator = lookup if(lookup) # TODO and klass.x.respond_to?(active_record_helper)) + md ? @method_details << md : @missing_methods << x + end + #@method_details.compact! .. currently we may need to map via the index on @method_details so don't remove nils for now + @method_details + end + + # The raw client supplied names + def method_names() + @method_details.collect( &:name ) + end + + # The true operator names discovered from model + def operator_names() + @method_details.collect( &:operator ) + end + + # Returns true if discovered methods contain every operator in mandatory_list + def contains_mandatory?( mandatory_list ) + [ [*mandatory_list] - operator_names].flatten.empty? + end + + def missing_mandatory( mandatory_list ) + [ [*mandatory_list] - operator_names].flatten + end + + end + end \ No newline at end of file