Class: Verquest::Properties::Collection

Inherits:
Base
  • Object
show all
Defined in:
lib/verquest/properties/collection.rb

Overview

Collection property type for arrays of objects

Represents an array of complex objects in the schema. Used for defining collections of structured data objects.

Examples:

Define a collection of items with inline properties

products = Verquest::Properties::Collection.new(name: :products)
products.add(Verquest::Properties::Field.new(name: :id, type: :string, required: true))
products.add(Verquest::Properties::Field.new(name: :name, type: :string))

Define a collection referencing an existing schema

products = Verquest::Properties::Collection.new(
  name: :products,
  item: ProductRequest
)

Instance Attribute Summary collapse

Attributes inherited from Base

#map, #name, #required

Instance Method Summary collapse

Methods inherited from Base

#mapping_value_key, #mapping_value_prefix

Constructor Details

#initialize(name:, item: nil, required: false, map: nil, **schema_options) ⇒ Collection

Initialize a new Collection property

Parameters:

  • name (String, Symbol)

    The name of the property

  • item (Verquest::Base, nil) (defaults to: nil)

    Optional reference to an external schema class

  • required (Boolean) (defaults to: false)

    Whether this property is required

  • map (String, nil) (defaults to: nil)

    The mapping path for this property

  • schema_options (Hash)

    Additional JSON schema options for this property

Raises:

  • (ArgumentError)

    If attempting to map a collection to the root



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/verquest/properties/collection.rb', line 29

def initialize(name:, item: nil, required: false, map: nil, **schema_options)
  raise ArgumentError, "You can not map collection to the root" if map == "/"

  @properties = {}

  @name = name.to_s
  @item = item
  @required = required
  @map = map
  @schema_options = schema_options&.transform_keys(&:to_s)
end

Instance Attribute Details

#itemObject (readonly, private)

Returns the value of attribute item.



144
145
146
# File 'lib/verquest/properties/collection.rb', line 144

def item
  @item
end

#propertiesObject (readonly, private)

Returns the value of attribute properties.



144
145
146
# File 'lib/verquest/properties/collection.rb', line 144

def properties
  @properties
end

#schema_optionsObject (readonly, private)

Returns the value of attribute schema_options.



144
145
146
# File 'lib/verquest/properties/collection.rb', line 144

def schema_options
  @schema_options
end

Instance Method Details

#add(property) ⇒ Verquest::Properties::Base

Add a child property to this collection’s item definition

Parameters:

Returns:



45
46
47
# File 'lib/verquest/properties/collection.rb', line 45

def add(property)
  properties[property.name] = property
end

#has_item?Boolean

Check if this collection references an external item schema

Returns:

  • (Boolean)

    True if the collection uses an external reference



52
53
54
# File 'lib/verquest/properties/collection.rb', line 52

def has_item?
  !item.nil?
end

#mapping(key_prefix:, value_prefix:, mapping:, version:) ⇒ Hash

Create mapping for this collection property and all its children

This method handles two different scenarios:

  1. When the collection references an external item schema (‘has_item?` returns true)

    • Creates mappings by transforming keys from the referenced item schema

    • Adds array notation ([]) to indicate this is a collection

    • Prefixes all keys and values with the appropriate paths

  2. When the collection has inline item properties

    • Creates mappings for each property in the collection items

    • Each property gets mapped with array notation and appropriate prefixes

Parameters:

  • key_prefix (Array<String>)

    Prefix for the source key

  • value_prefix (Array<String>)

    Prefix for the target value

  • mapping (Hash)

    The mapping hash to be updated

  • version (String, nil)

    The version to create mapping for

Returns:

  • (Hash)

    The updated mapping hash



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/verquest/properties/collection.rb', line 126

def mapping(key_prefix:, value_prefix:, mapping:, version:)
  if has_item?
    value_key_prefix = mapping_value_key(value_prefix: value_prefix, collection: true)

    reference_mapping = item.mapping(version:).dup
    reference_mapping.transform_keys! { "#{(key_prefix + [name]).join(".")}[].#{_1}" }
    reference_mapping.transform_values! { "#{value_key_prefix}.#{_1}" }

    mapping.merge!(reference_mapping)
  else
    properties.values.each do |property|
      property.mapping(key_prefix: key_prefix + ["#{name}[]"], value_prefix: mapping_value_prefix(value_prefix: value_prefix, collection: true), mapping:, version:)
    end
  end
end

#to_schemaHash

Generate JSON schema definition for this collection property

Returns:

  • (Hash)

    The schema definition for this collection property



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/verquest/properties/collection.rb', line 59

def to_schema
  if has_item?
    {
      name => {
        "type" => "array",
        "items" => {
          "$ref" => item.to_ref
        }
      }.merge(schema_options)
    }
  else
    {
      name => {
        "type" => "array",
        "items" => {
          "type" => "object",
          "required" => properties.values.select(&:required).map(&:name),
          "properties" => properties.transform_values { |property| property.to_schema[property.name] }
        }
      }.merge(schema_options)
    }
  end
end

#to_validation_schema(version: nil) ⇒ Hash

Generate validation schema for this collection property

Parameters:

  • version (String, nil) (defaults to: nil)

    The version to generate validation schema for

Returns:

  • (Hash)

    The validation schema for this collection property



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/verquest/properties/collection.rb', line 87

def to_validation_schema(version: nil)
  if has_item?
    {
      name => {
        "type" => "array",
        "items" => item.to_validation_schema(version: version)
      }.merge(schema_options)
    }
  else
    {
      name => {
        "type" => "array",
        "items" => {
          "type" => "object",
          "required" => properties.values.select(&:required).map(&:name),
          "properties" => properties.transform_values { |property| property.to_validation_schema(version: version)[property.name] }
        }
      }.merge(schema_options)
    }
  end
end