Class: ARLoader::MethodMapper

Inherits:
Object
  • Object
show all
Defined in:
lib/ar_loader/method_mapper.rb

Constant Summary collapse

@@has_many =
Hash.new
@@belongs_to =
Hash.new
@@assignments =
Hash.new
@@column_types =
Hash.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMethodMapper

Returns a new instance of MethodMapper.



32
33
34
35
# File 'lib/ar_loader/method_mapper.rb', line 32

def initialize
  @method_details = []
  @headers = []
end

Instance Attribute Details

#header_rowObject

Returns the value of attribute header_row.



24
25
26
# File 'lib/ar_loader/method_mapper.rb', line 24

def header_row
  @header_row
end

#headersObject

Returns the value of attribute headers.



24
25
26
# File 'lib/ar_loader/method_mapper.rb', line 24

def headers
  @headers
end

#method_detailsObject

Returns the value of attribute method_details.



25
26
27
# File 'lib/ar_loader/method_mapper.rb', line 25

def method_details
  @method_details
end

#missing_methodsObject

Returns the value of attribute missing_methods.



25
26
27
# File 'lib/ar_loader/method_mapper.rb', line 25

def missing_methods
  @missing_methods
end

Class Method Details

.assignmentsObject



189
190
191
# File 'lib/ar_loader/method_mapper.rb', line 189

def self.assignments
  @@assignments
end

.assignments_for(klass) ⇒ Object



208
209
210
# File 'lib/ar_loader/method_mapper.rb', line 208

def self.assignments_for(klass)
  @@assignments[klass] || []
end

.belongs_toObject

TODO - remove use of class variables - not good Ruby design



176
177
178
# File 'lib/ar_loader/method_mapper.rb', line 176

def self.belongs_to
  @@belongs_to
end

.belongs_to_for(klass) ⇒ Object



197
198
199
# File 'lib/ar_loader/method_mapper.rb', line 197

def self.belongs_to_for(klass)
  @@belongs_to[klass] || []
end

.clearObject



163
164
165
166
167
168
169
# File 'lib/ar_loader/method_mapper.rb', line 163

def self.clear
  @@belongs_to.clear
  @@has_many.clear
  @@assignments.clear
  @@column_types.clear
  self.has_one.clear
end

.column_key(klass, column) ⇒ Object



171
172
173
# File 'lib/ar_loader/method_mapper.rb', line 171

def self.column_key(klass, column)
  "#{klass.name}:#{column}"
end

.column_type_for(klass, column) ⇒ Object



211
212
213
# File 'lib/ar_loader/method_mapper.rb', line 211

def self.column_type_for(klass, column)
  @@column_types[klass] ?  @@column_types[klass][column] : []
end

.column_typesObject



192
193
194
# File 'lib/ar_loader/method_mapper.rb', line 192

def self.column_types
  @@column_types
end

.find_method_detail(klass, external_name) ⇒ Object

Find the proper format of name, appropriate call + column type for a given name. e.g Given users entry in spread sheet check for pluralization, missing underscores etc

If not nil, returned method can be used directly in for example klass.new.send( call, .… )



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/ar_loader/method_mapper.rb', line 125

def self.find_method_detail( klass, external_name )
  assign = nil

  name = external_name.to_s

  # TODO - check out regexp to do this work better plus Inflections ??
  # Want to be able to handle any of ["Count On hand", 'count_on_hand', "Count OnHand", "COUNT ONHand" etc]
  [
    name,
    name.tableize,
    name.gsub(' ', '_'),
    name.gsub(' ', '_').downcase,
    name.gsub(/(\s+)/, '_').downcase,
    name.gsub(' ', ''),
    name.gsub(' ', '').downcase,
    name.gsub(' ', '_').underscore].each do |n|
  
    assign = (assignments_for(klass).include?(n)) ? n : nil
  
    return MethodDetail.new(name, klass, assign, :assignment, @@column_types[klass]) if(assign)

    assign = (has_one_for(klass).include?(n)) ? n : nil
  
    return MethodDetail.new(name, klass, assign, :has_one, @@column_types[klass]) if(assign)

    assign = (has_many_for(klass).include?(n)) ?  n : nil
  
    return MethodDetail.new(name, klass, assign, :has_many, @@column_types[klass]) if(assign)
  
    assign = (belongs_to_for(klass).include?(n)) ? n : nil
  
    return MethodDetail.new(name, klass, assign, :belongs_to, @@column_types[klass]) if(assign)
  
  end

  nil
end

.find_operators(klass, options = {}) ⇒ Object

Create picture of the operators for assignment available on an AR model, including via associations (which provide both << and = ) Optoipns: :reload => clear caches and reperform lookup :instance_methods => if true include instance method type assignment operators as well as model’s pure columns



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ar_loader/method_mapper.rb', line 78

def self.find_operators(klass, options = {} )

  # Find the has_many associations which can be populated via <<
  if( options[:reload] || @@has_many[klass].nil? )
    @@has_many[klass] = klass.reflect_on_all_associations(:has_many).map { |i| i.name.to_s }
    klass.reflect_on_all_associations(:has_and_belongs_to_many).inject(@@has_many[klass]) { |x,i| x << i.name.to_s }
  end
  # puts "DEBUG: Has Many Associations:", @@has_many[klass].inspect

  # Find the belongs_to associations which can be populated via  Model.belongs_to_name = OtherArModelObject
  if( options[:reload] || @@belongs_to[klass].nil? )
    @@belongs_to[klass] = klass.reflect_on_all_associations(:belongs_to).map { |i| i.name.to_s }
  end

  #puts "Belongs To Associations:", @@belongs_to[klass].inspect

  # Find the has_one associations which can be populated via  Model.has_one_name = OtherArModelObject
  if( options[:reload] || self.has_one[klass].nil? )
    self.has_one[klass] = klass.reflect_on_all_associations(:has_one).map { |i| i.name.to_s }
  end

  #puts "has_one Associations:", self.has_one[klass].inspect

  # Find the model's column associations which can be populated via = value
  if( options[:reload] || @@assignments[klass].nil? )

    @@assignments[klass] = klass.column_names
    @@assignments[klass] += klass.instance_methods.grep(/=/).map{|i| i.gsub(/=/, '')} if(options[:instance_methods] == true)
    @@assignments[klass] -= @@has_many[klass] if(@@has_many[klass])
    @@assignments[klass] -= @@belongs_to[klass] if(@@belongs_to[klass])
    @@assignments[klass] -= self.has_one[klass] if(self.has_one[klass])
 
    @@assignments[klass].uniq!

    @@assignments[klass].each do |assign|
      @@column_types[klass] ||= {}
      found = klass.columns.find{ |col| col.name == assign }
      @@column_types[klass].merge!( found.name => found) if found
    end
  end
end

.has_manyObject



180
181
182
# File 'lib/ar_loader/method_mapper.rb', line 180

def self.has_many
  @@has_many
end

.has_many_for(klass) ⇒ Object



200
201
202
# File 'lib/ar_loader/method_mapper.rb', line 200

def self.has_many_for(klass)
  @@has_many[klass] || []
end

.has_oneObject



184
185
186
187
# File 'lib/ar_loader/method_mapper.rb', line 184

def self.has_one
  @has_one ||= {}
  @has_one
end

.has_one_for(klass) ⇒ Object



204
205
206
# File 'lib/ar_loader/method_mapper.rb', line 204

def self.has_one_for(klass)
  self.has_one[klass] || []
end

Instance Method Details

#contains_mandatory?(mandatory_list) ⇒ Boolean

Returns true if discovered methods contain every operator in mandatory_list

Returns:

  • (Boolean)


63
64
65
66
# File 'lib/ar_loader/method_mapper.rb', line 63

def contains_mandatory?( mandatory_list )
  puts operator_names.inspect
  [mandatory_list - operator_names].flatten.empty?
end

#method_namesObject

The raw client supplied names



53
54
55
# File 'lib/ar_loader/method_mapper.rb', line 53

def method_names()
  @method_details.collect( &:name )
end

#missing_mandatory(mandatory_list) ⇒ Object



68
69
70
# File 'lib/ar_loader/method_mapper.rb', line 68

def missing_mandatory( mandatory_list )
  [mandatory_list - operator_names].flatten
end

#operator_namesObject

The true operator names discovered from model



58
59
60
# File 'lib/ar_loader/method_mapper.rb', line 58

def operator_names()
  @method_details.collect( &:operator )
end

#populate_methods(klass, method_list) ⇒ Object

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



41
42
43
44
45
46
47
48
49
50
# File 'lib/ar_loader/method_mapper.rb', line 41

def populate_methods( klass, method_list )
  @method_details, @missing_methods = [], []

  method_list.each do |x|
    md = MethodMapper::find_method_detail( klass, x )
    md ? @method_details << md : @missing_methods << x
  end
  #@method_details.compact!  .. currently we may neeed to map via the index on @method_details so don't remove nils for now
  @method_details
end