class Onsi::Model::ModelRenderer
The class that holds attributes and relationships for a model's version.
@note You shouldn't ever have to directly interact with one of
these classes.
@author Maddie Schipper @since 1.0.0
Constants
- DATETIME_FORMAT
The default date-time format for a rendered Date and Time. (ISO-8601)
- DATE_FORMAT
The default date format for a rendered Date. (ISO-8601)
Attributes
The name of the id attribute on the model
Public Class Methods
Create a new ModelRenderer
@private
# File lib/onsi/model.rb, line 102 def initialize(id_attr) @id_attr = id_attr @attributes = {} @relationships = {} @metadata = {} end
Public Instance Methods
Add an attribute to the rendered attributes.
@param name [String, Symbol, to_sym] The name of the attribute.
If no block is passed the name will be called on the {Onsi::Resource#object}
@param block [Block] The block used to fetch a dynamic attribute.
It will be executed in the context of the {Onsi::Resource#object}
@example
api_render(:v1) do attribute(:first_name) attribute(:last_name) attribute(:full_name) { "#{first_name} #{last_name}" } # ... end
# File lib/onsi/model.rb, line 140 def attribute(name, &block) @attributes[name.to_sym] = block || name end
# File lib/onsi/model.rb, line 207 def legacy_relationship_render! @legacy_relationship_render = true end
Add a metadata value to the rendered object's meta.
@param name [#to_sym] The name for the meta value.
@param block [Block] The block used to fetch the meta value.
It will be executed in the context of the {Onsi::Resource#object}
# File lib/onsi/model.rb, line 172 def meta(name, &block) @metadata[name.to_sym] = block end
Add a relationship to the rendered relationships.
@param name [Symbol, to_sym] The relationship name.
@param type [String, to_s] The relationship type.
@param block [Block] The block used to fetch a dynamic attribute.
It will be executed in the context of the {Onsi::Resource#object}
@example
api_render(:v1) do relationship(:team, :team) # ... end
# File lib/onsi/model.rb, line 161 def relationship(name, type, &block) @relationships[name.to_sym] = { type: type, attr: block || name } end
Render all attributes
@private
# File lib/onsi/model.rb, line 180 def render_attributes(object) @attributes.each_with_object({}) do |(key, value), attrs| val = value.respond_to?(:call) ? object.instance_exec(&value) : object.send(value) attrs[key.to_s] = format_attribute(val) end end
Render all metadata
@private
# File lib/onsi/model.rb, line 201 def render_metadata(object) @metadata.each_with_object({}) do |(key, block), meta| meta[key.to_s] = object.instance_exec(&block) end end
Render all relationships
@private
# File lib/onsi/model.rb, line 191 def render_relationships(object) @relationships.each_with_object({}) do |(key, value), rels| render_relationship_entry(object, key, value, rels) end end
The type name.
@param name [String, nil] The resource object type name.
@note Not required. If there is no type, the class name will be used
when rendering the object. (Name is underscored)
# File lib/onsi/model.rb, line 116 def type(name = nil) @type = name if name @type end
Private Instance Methods
# File lib/onsi/model.rb, line 266 def format_attribute(value) case value when Date value.strftime(DATE_FORMAT) when DateTime, Time value.utc.strftime(DATETIME_FORMAT) when String value.presence else value end end
# File lib/onsi/model.rb, line 230 def format_relationship(relationship, value) if @legacy_relationship_render == true return legacy_format_relationship(relationship, value) end case relationship when Enumerable if relationship.empty? return [] end relationship.map { |v| { 'type' => value[:type].to_s, 'id' => v.to_s } } else unless relationship.to_s.present? return nil end { 'type' => value[:type].to_s, 'id' => relationship.to_s } end end
# File lib/onsi/model.rb, line 222 def get_relationship_value(attr, object) if attr.respond_to?(:call) object.instance_exec(&attr) else object.send("#{attr}_id") end end
# File lib/onsi/model.rb, line 254 def legacy_format_relationship(relationship, value) case relationship when Array relationship.map { |v| { 'type' => value[:type].to_s, 'id' => v.to_s } } else { 'type' => value[:type].to_s, 'id' => relationship.to_s } end end
# File lib/onsi/model.rb, line 213 def render_relationship_entry(object, key, value, rels) attr = value[:attr] relationship = get_relationship_value(attr, object) data = format_relationship(relationship, value) rels[key.to_s] = { 'data' => data } end