Module: SchemaTools::Modules::Hash
- Included in:
- Hash
- Defined in:
- lib/schema_tools/modules/hash.rb
Instance Method Summary collapse
-
#from_schema(obj, opts = {}) ⇒ Hash{String=>{String=>Mixed}}
Create a Hash with the available (api)object attributes defined in the according schema properties.
-
#parse_links(obj, schema) ⇒ Object
- Parse the link section of the schema by replacing id in urls === Returns <Array>
- <nil>
-
no links present.
Instance Method Details
#from_schema(obj, opts = {}) ⇒ Hash{String=>{String=>Mixed}}
Create a Hash with the available (api)object attributes defined in the according schema properties. This is the meat of the object-to-api-markup workflow
Example
obj = Invoice.new(:title =>'hello world', :number=>'4711')
obj_hash = SchemaTools::Hash.from_schema(obj)
=> { 'invoice' =>{'title'=>'hello world', 'number'=>'4711' } }
obj_hash = Schema.to_hash_from_schema(obj, fields: ['title'])
=> { 'invoice' =>{'title'=>'hello world' } }
obj_hash = Schema.to_hash_from_schema(obj, class_name: :document)
=> { 'document' =>{'title'=>'hello world' } }
a lowercase underscored name and it MUST have an existing schema file. Use it to override the default, which is obj.class.name properties are used.
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 85 86 87 88 89 90 91 |
# File 'lib/schema_tools/modules/hash.rb', line 39 def from_schema(obj, opts={}) fields = opts[:fields] # get objects class name without inheritance real_class_name = obj.class.name.split('::').last.underscore class_name = opts[:class_name] || real_class_name data = {} # get schema schema = SchemaTools::Reader.read(class_name, opts[:path]) # iterate over the defined schema fields schema['properties'].each do |field, prop| next if fields && !fields.include?(field) if prop['type'] == 'array' data[field] = [] # always set an empty array if obj.respond_to?( field ) && rel_objects = obj.send( field ) rel_objects.each do |rel_obj| data[field] << if prop['properties'] && prop['properties']['$ref'] #got schema describing the objects from_schema(rel_obj, opts) else rel_obj end end end elsif prop['type'] == 'object' # a singular related object data[field] = nil # always set empty val if obj.respond_to?( field ) && rel_obj = obj.send( field ) if prop['properties'] && prop['properties']['$ref'] data[field] = from_schema(rel_obj, opts) else # NO recursion directly get values from related object. Does # NOT allow deeper nesting so you MUST define an own schema to be save data[field] = {} prop['properties'].each do |fld, prp| data[field][fld] = rel_obj.send(fld) if obj.respond_to?(field) end end end else # a simple field is only added if the object knows it data[field] = obj.send(field) if obj.respond_to?(field) end end hsh = { "#{class_name}" => data } #add links if present links = parse_links(obj, schema) links && hsh['links'] = links hsh end |
#parse_links(obj, schema) ⇒ Object
97 98 99 100 101 102 103 104 105 |
# File 'lib/schema_tools/modules/hash.rb', line 97 def parse_links(obj, schema) links = [] schema['links'] && schema['links'].each do |link| links << { 'rel' => link['rel'], 'href' => link['href'].gsub(/\{id\}/, "#{obj.id}") } end links.uniq # return links only if not empty links.empty? ? nil : links end |