Class: Treaty::Entity::Attribute::Builder::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/treaty/entity/attribute/builder/base.rb

Overview

Base DSL builder for defining attributes in request/response definitions.

Purpose

Provides the DSL interface for defining attributes within objects. Handles method_missing magic to support type-based method calls.

Responsibilities

  1. DSL Interface - Provides clean syntax for attribute definitions
  2. Method Dispatch - Routes type methods (string, integer, etc.) to attribute creation
  3. Helper Support - Handles helper symbols in various positions
  4. Nesting Tracking - Tracks nesting level for nested attributes
  5. Entity Reuse - Supports use_entity for copying attributes from Entity classes

DSL Usage

The builder enables this clean DSL syntax:

request do
  object :user do
    string :name
    integer :age, default: 18
    object :profile do
      string :bio
    end
  end
end

Entity Reuse

You can use use_entity to copy attributes from an Entity class:

object :author do
  use_entity(AuthorEntity)
end

Note: use_entity must be the only statement in the block.

Method Dispatch

Type-based Methods

When you call string :name, it routes through method_missing:

  1. string becomes the type
  2. :name becomes the attribute name
  3. Calls attribute(:name, :string, ...)

Helper Position Handling

Handles helpers in different positions:

string :required, :name    # Helper first, then name
string :name, :required    # Name first, then helper

Both resolve to the same attribute definition.

Nesting

Tracks nesting level for:

  • Validation (enforcing maximum nesting depth)
  • Error messages (showing context)

Maximum nesting level is configured in Treaty::Engine.config.

Subclass Requirements

Subclasses must implement:

  • create_attribute - Creates the appropriate attribute type (Request/Response)
  • deep_copy_attribute - Deep copies an attribute with adjusted nesting level

Architecture

Used by:

  • Request::Builder - For request attribute definitions
  • Response::Builder - For response attribute definitions
  • Entity::Builder - For entity attribute definitions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(collection_of_attributes, nesting_level) ⇒ Base

Creates a new builder instance

Parameters:

  • Collection to add attributes to

  • Current nesting depth



96
97
98
99
100
101
# File 'lib/treaty/entity/attribute/builder/base.rb', line 96

def initialize(collection_of_attributes, nesting_level)
  @collection_of_attributes = collection_of_attributes
  @nesting_level = nesting_level
  @use_entity_called = false
  @attributes_defined = false
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(type, name, *helpers, **options, &block) ⇒ void

This method returns an undefined value.

Handles DSL methods like string :name where method name is the type

Parameters:

  • The attribute type (method name)

  • The attribute name (first argument)

  • Helper symbols

  • Attribute options

  • Block for nested attributes



160
161
162
163
164
165
166
167
# File 'lib/treaty/entity/attribute/builder/base.rb', line 160

def method_missing(type, name, *helpers, **options, &block)
  if name.is_a?(Symbol) && HelperMapper.helper?(name)
    helpers.unshift(name)
    name = helpers.shift
  end

  attribute(name, type, *helpers, **options, &block)
end

Instance Attribute Details

#collection_of_attributesObject (readonly)

Returns the value of attribute collection_of_attributes.



89
90
91
# File 'lib/treaty/entity/attribute/builder/base.rb', line 89

def collection_of_attributes
  @collection_of_attributes
end

#nesting_levelObject (readonly)

Returns the value of attribute nesting_level.



89
90
91
# File 'lib/treaty/entity/attribute/builder/base.rb', line 89

def nesting_level
  @nesting_level
end

Instance Method Details

#attribute(name, type, *helpers, **options, &block) ⇒ void

This method returns an undefined value.

Defines an attribute with explicit type

Parameters:

  • The attribute name

  • The attribute type

  • Helper symbols (:required, :optional)

  • Attribute options

  • Block for nested attributes



137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/treaty/entity/attribute/builder/base.rb', line 137

def attribute(name, type, *helpers, **options, &block)
  validate_no_use_entity_called!

  @attributes_defined = true

  @collection_of_attributes << create_attribute(
    name,
    type,
    *helpers,
    nesting_level: @nesting_level,
    **options,
    &block
  )
end

#respond_to_missing?(name) ⇒ Boolean

Checks if method should be handled by method_missing

Parameters:

  • Method name

Returns:



173
174
175
# File 'lib/treaty/entity/attribute/builder/base.rb', line 173

def respond_to_missing?(name, *)
  super
end

#use_entity(entity_class) ⇒ void

This method returns an undefined value.

Uses an Entity class to copy its attributes into this builder's collection. Must be the ONLY statement in the block - no other attributes allowed.

Examples:

Using an Entity in a nested object

object :author do
  use_entity(AuthorEntity)
end

Using an Entity in a nested array

array :items, :optional do
  use_entity(ItemEntity)
end

Parameters:

  • Entity class (must be Treaty::Entity::Base subclass)

Raises:

  • if entity_class is invalid

  • if mixed with other attributes



120
121
122
123
124
125
126
127
# File 'lib/treaty/entity/attribute/builder/base.rb', line 120

def use_entity(entity_class)
  validate_use_entity_preconditions!
  validate_entity_class!(entity_class)

  @use_entity_called = true

  copy_attributes_from_entity(entity_class)
end