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

id_attr[R]

The name of the id attribute on the model

Public Class Methods

new(id_attr) click to toggle source

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

attribute(name, &block) click to toggle source

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
legacy_relationship_render!() click to toggle source
# File lib/onsi/model.rb, line 207
def legacy_relationship_render!
  @legacy_relationship_render = true
end
meta(name, &block) click to toggle source

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
relationship(name, type, &block) click to toggle source

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_attributes(object) click to toggle source

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_metadata(object) click to toggle source

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_relationships(object) click to toggle source

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
type(name = nil) click to toggle source

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

format_attribute(value) click to toggle source
# 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
format_relationship(relationship, value) click to toggle source
# 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
get_relationship_value(attr, object) click to toggle source
# 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
legacy_format_relationship(relationship, value) click to toggle source
# 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
render_relationship_entry(object, key, value, rels) click to toggle source
# 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