Module: HashEngine::Extract
Instance Method Summary collapse
- #append_error_for_required_fields(results, message, instructions) ⇒ Object
- #cast_value(return_val, field, field_instructions) ⇒ Object
-
#extract(objects, instructions) ⇒ Object
Collects data from a root object based on the provided instructions hash.
- #fetch_attributes(object, parent_name, object_hash, results) ⇒ Object
-
#fetch_method(object, field, field_instructions) ⇒ Object
Identify the method to be called.
- #fetch_method_args(field, field_instructions) ⇒ Object
- #fetch_method_array(field, field_instructions) ⇒ Object
- #fetch_objects(objects_hash, objects_to_walk, instructions) ⇒ Object
- #fetch_value(field, field_instructions, object, parent_name, object_hash, results) ⇒ Object
- #set_result_or_recurse(return_val, parent_name, field, field_instructions, results) ⇒ Object
Methods included from Format
#add_format, #format, #formats
Instance Method Details
#append_error_for_required_fields(results, message, instructions) ⇒ Object
132 133 134 135 136 137 |
# File 'lib/hash_engine/extract.rb', line 132 def append_error_for_required_fields(results, , instructions) # Only log an error for required fields. if (!instructions || instructions.fetch('required', true)) results[:error] << end end |
#cast_value(return_val, field, field_instructions) ⇒ Object
100 101 102 103 104 105 106 |
# File 'lib/hash_engine/extract.rb', line 100 def cast_value(return_val, field, field_instructions) if field_instructions && field_instructions.has_key?('cast') return_val = format_value(return_val, field_instructions['cast']) else return_val end end |
#extract(objects, instructions) ⇒ Object
Collects data from a root object based on the provided instructions hash. The data is returned as a flat hash. A hash is used to specify the set of attributes which should be included in the .
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/hash_engine/extract.rb', line 13 def extract(objects, instructions) if instructions.nil? || instructions.empty? # can't do anything {:error => ['Missing instructions']} else objects_to_walk = instructions.keys if objects.nil? {:error => ['Missing object(s)']} else if objects.is_a?(Hash) # hash path objects_given = objects.keys if delta = objects_to_walk - objects_given and !delta.empty? {:error => ["Missing object(s): #{(delta).sort.join(', ')}"]} else # instructions for objects a, b, c # given objects a, b, c fetch_objects(objects_hash, objects_to_walk, instructions) end else # single object path if objects_to_walk.size > 1 {:error => ["Instructions given for #{objects_to_walk.sort.join(', ')} but only 1 object given"]} else # instructions for 1 object # given 1 object object_name = objects_to_walk.first fetch_objects({object_name => objects}, objects_to_walk, instructions) end end end end end |
#fetch_attributes(object, parent_name, object_hash, results) ⇒ Object
61 62 63 64 65 66 67 68 |
# File 'lib/hash_engine/extract.rb', line 61 def fetch_attributes(object, parent_name, object_hash, results) object_hash.each_pair do |field, field_instructions| # Command keywords are reserved and will not be walked. unless @@reserved_keys.has_key?(field) fetch_value(field, field_instructions, object, parent_name, object_hash, results) end end end |
#fetch_method(object, field, field_instructions) ⇒ Object
Identify the method to be called.
114 115 116 117 |
# File 'lib/hash_engine/extract.rb', line 114 def fetch_method(object, field, field_instructions) fetch_method_array(field, field_instructions).detect {|method| object.respond_to?(method) } end |
#fetch_method_args(field, field_instructions) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/hash_engine/extract.rb', line 119 def fetch_method_args(field, field_instructions) if field_instructions && field_instructions['method_args'] # if args specified make sure its an array if field_instructions['method_args'].is_a?(Array) field_instructions['method_args'] else [ field_instructions['method_args'] ] end else [] end end |
#fetch_method_array(field, field_instructions) ⇒ Object
108 109 110 111 |
# File 'lib/hash_engine/extract.rb', line 108 def fetch_method_array(field, field_instructions) # Don't use compact! => returns nil if unchanged instead of returning the unchanged array [(field_instructions && field_instructions['method']), field, field+'?'].compact end |
#fetch_objects(objects_hash, objects_to_walk, instructions) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/hash_engine/extract.rb', line 48 def fetch_objects(objects_hash, objects_to_walk, instructions) results = {:error => []} objects_to_walk.each do |object_name| instructions[object_name].each_pair do |field, field_instructions| # Command keywords are reserved and will not be walked. unless @@reserved_keys.has_key?(field) fetch_value(field, field_instructions, objects_hash[object_name], object_name, instructions[object_name], results) end end end results end |
#fetch_value(field, field_instructions, object, parent_name, object_hash, results) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/hash_engine/extract.rb', line 70 def fetch_value(field, field_instructions, object, parent_name, object_hash, results) # puts " Field: #{field} field_instructions #{field_instructions.inspect} object #{object.inspect}" method = fetch_method(object, field, field_instructions) # puts " Method: #{method.inspect}" args = fetch_method_args(field, field_instructions) if method return_val = object.send(method, *args) return_val = cast_value(return_val, field, field_instructions) # check if we need to dive deeper into recursion set_result_or_recurse(return_val, parent_name, field, field_instructions, results) else append_error_for_required_fields(results, "#{parent_name} does not respond to any of: #{fetch_method_array(field, field_instructions).join(', ')}", field_instructions) end end |
#set_result_or_recurse(return_val, parent_name, field, field_instructions, results) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/hash_engine/extract.rb', line 86 def set_result_or_recurse(return_val, parent_name, field, field_instructions, results) if field_instructions && field_instructions.keys.any? {|k| !@@reserved_keys.has_key?(k) } # yes, dive! if return_val.nil? append_error_for_required_fields(results, "Missing required field: #{parent_name}.#{field}", field_instructions) else fetch_attributes(return_val, "#{parent_name}.#{field}", field_instructions, results) end else # no, add to results results[field] = return_val end end |