Class: GrapeOpenapi3::Readers::EntityReader

Inherits:
Object
  • Object
show all
Defined in:
lib/grape_openapi3/readers/entity_reader.rb

Overview

Reads Grape::Entity subclasses and converts them to OpenAPI 3.0 schema objects.

Maintains an internal registry so that:

- Each entity class is only processed once
- Circular references are broken (placeholder set before recursing)
- Nested entities (using: SomeEntity) become $ref pointers

Schema naming (collision-free):

By default each schema is named after the entity's last namespace segment
(e.g. "MenteeResponse"). When two DIFFERENT entity classes share that short
name, #prepare disambiguates them deterministically using the shortest
namespace suffix that makes them unique (e.g. "Mentors_MenteeResponse" vs
"Kids_MenteeResponse"). Names are stable regardless of registration order.

Usage:

reader = EntityReader.new(separator: "_")
reader.prepare([RootEntityA, RootEntityB])  # optional but recommended
name = reader.register(MyEntity)            # → schema name, adds to schemas
reader.schemas                              # → { "MyEntity" => { ... } }

Constant Summary collapse

REPRESENT_EXPOSURE =
"Grape::Entity::Exposure::RepresentExposure"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(separator: "_") ⇒ EntityReader

Returns a new instance of EntityReader.



29
30
31
32
33
# File 'lib/grape_openapi3/readers/entity_reader.rb', line 29

def initialize(separator: "_")
  @schemas   = {}
  @separator = separator
  @name_map  = {} # full Ruby class name => assigned schema name
end

Instance Attribute Details

#schemasObject (readonly)

Returns the value of attribute schemas.



27
28
29
# File 'lib/grape_openapi3/readers/entity_reader.rb', line 27

def schemas
  @schemas
end

Instance Method Details

#prepare(root_entities) ⇒ Object

Walk the entity graph reachable from the given root entities and assign a stable, collision-free schema name to every entity. Call before #register.



37
38
39
40
41
42
# File 'lib/grape_openapi3/readers/entity_reader.rb', line 37

def prepare(root_entities)
  all = []
  Array(root_entities).each { |e| collect(resolve_class(e), all) }
  @name_map = build_name_map(all)
  self
end

#register(entity_class) ⇒ Object

Register an entity class and return its schema name. Safe to call multiple times with the same class.



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/grape_openapi3/readers/entity_reader.rb', line 46

def register(entity_class)
  entity_class = resolve_class(entity_class)
  return nil unless entity_class.respond_to?(:root_exposures)

  name = schema_name(entity_class)
  return name if @schemas.key?(name)

  @schemas[name] = nil   # break circular refs before recursing
  @schemas[name] = build_schema(entity_class)
  name
end