class TeamApi::CrossReferenceData

Provides a collection with the ability to replace identifiers with more detailed cross-reference values from another collection, and with the ability to construct its own cross-reference values to assign to values from other collections.

The intent is to provide enough cross-reference information to surface in an API without requiring the client to join the data necessary to produce cross-links. For example, instead of surfacing `['mbland']` in a list of team members, this class will produce `[{'name' => 'mbland', 'full_name'

> 'Mike Bland', 'first_name' => 'Mike', 'last_name' => 'Bland'}]`, which

the client can use to more easily sort multiple values and transform into: `<a href=“Mike”>hub.18f.gov/team/mbland/“>Mike Bland</a>`.

Attributes

collection_name[RW]
data[RW]
item_xref_fields[RW]
public_mode[RW]

Public Class Methods

new(site, collection_name, item_xref_fields) click to toggle source

@param site [Jekyll::Site] site object @param collection_name [String] name of collection within site.data @param field_to_xref [String] name of the field to cross-reference @param item_xref_fields [Array<String>] list of fields from which to

produce cross-references for this collection
# File lib/team_api/cross_reference_data.rb, line 30
def initialize(site, collection_name, item_xref_fields)
  @collection_name = collection_name
  @data = site.data[collection_name] || {}
  @item_xref_fields = item_xref_fields
  @public_mode = site.config['public']
end

Public Instance Methods

create_xrefs(target, source_to_target_field: nil, alternate_names: nil) click to toggle source

Translates identifiers into cross-reference values in both this object's collection and the `target` collection.

This object's collection is considered the “source”, and references to its values will be injected into “target”. For each “source” object, `source` should be an existing field containing identifiers that are keys into `target.data`. The `target` collection values should not contain a `target` field; that field will be created by this method.

@param target [CrossReferenceData] contains data to cross-reference with

items from this object's collection

@param source_to_target_field [String] if specified, the field from this

collection's objects that contain identifiers of objects stored within
target; if not specified, target.collection_name will be used instead
# File lib/team_api/cross_reference_data.rb, line 58
def create_xrefs(target, source_to_target_field: nil, alternate_names: nil)
  item_xref_fields << 'deprecated_name'

  target_collection_field = source_to_target_field || target.collection_name
  data.values.each do |source|
    create_xrefs_for_source source, target_collection_field, target, alternate_names
  end
  target.data.values.each { |item| (item[collection_name] || []).uniq! }
end
item_to_xref(item) click to toggle source

Selects fields from `item` to produce a smaller hash as a cross-reference.

# File lib/team_api/cross_reference_data.rb, line 39
def item_to_xref(item)
  item.select { |field, _| item_xref_fields.include? field }
end

Private Instance Methods

create_xrefs_for_source(source, target_collection_field, target, alternate_names) click to toggle source
# File lib/team_api/cross_reference_data.rb, line 70
def create_xrefs_for_source(source, target_collection_field, target, alternate_names)
  source_xref = item_to_xref source
  target_ids = filter_target_ids target, source, target_collection_field, alternate_names
  link_source_to_targets source_xref, target_ids, target
  source[target_collection_field] = target_xrefs target, target_ids
end
filter_target_ids(target_xref, source_item, target_collection_field, alternate_names) click to toggle source
# File lib/team_api/cross_reference_data.rb, line 77
def filter_target_ids(target_xref, source_item, target_collection_field, alternate_names)
  (source_item[target_collection_field] || []).map do |target_id|
    if target_xref.data.member? target_id
      target_id
    elsif alternate_names && alternate_names[target_id] &&
        (target_xref.data.member? alternate_names[target_id])
      alternate_names[target_id]
    elsif !public_mode
      fail UnknownCrossReferenceTargetId, unknown_cross_reference_msg(
        collection_name, source_item, target_collection_field,
        target_xref, target_id)
    end
  end.compact
end
target_xrefs(target_xref, target_ids) click to toggle source
# File lib/team_api/cross_reference_data.rb, line 107
def target_xrefs(target_xref, target_ids)
  target_ids.map { |id| target_xref.item_to_xref target_xref.data[id] }
end
unknown_cross_reference_msg(collection_name, source_item, target_collection_field, target_xref, target_id) click to toggle source
# File lib/team_api/cross_reference_data.rb, line 92
def unknown_cross_reference_msg(collection_name,
  source_item, target_collection_field, target_xref, target_id)
  "source collection: \"#{collection_name}\" " \
    "source xref: #{item_to_xref source_item} " \
    "target collection field: \"#{target_collection_field}\" " \
    "target collection: \"#{target_xref.collection_name}\" " \
    "target ID: \"#{target_id}\""
end