Class: Rbdantic::JsonSchema::Generator
- Inherits:
-
Object
- Object
- Rbdantic::JsonSchema::Generator
- Defined in:
- lib/rbdantic/json_schema/generator.rb
Overview
Generate JSON Schema from model class
Constant Summary collapse
- SCHEMA_VERSION =
JSON Schema version
"https://json-schema.org/draft/2020-12/schema"
Class Method Summary collapse
-
.generate(model_class, **options) ⇒ Hash
Generate schema for a model class.
Instance Method Summary collapse
- #generate ⇒ Object
-
#initialize(model_class, title: nil, description: nil, schema_id: nil, include_defaults: true, top_level: true, defs_registry: nil, by_alias: false) ⇒ Generator
constructor
A new instance of Generator.
Constructor Details
#initialize(model_class, title: nil, description: nil, schema_id: nil, include_defaults: true, top_level: true, defs_registry: nil, by_alias: false) ⇒ Generator
Returns a new instance of Generator.
25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/rbdantic/json_schema/generator.rb', line 25 def initialize(model_class, title: nil, description: nil, schema_id: nil, include_defaults: true, top_level: true, defs_registry: nil, by_alias: false) @model_class = model_class @title = title || model_class.name @description = description @schema_id = schema_id @include_defaults = include_defaults @top_level = top_level @by_alias = by_alias # Use provided registry or create one at top level @defs_registry = defs_registry || (top_level ? DefsRegistry.new : nil) end |
Class Method Details
.generate(model_class, **options) ⇒ Hash
Generate schema for a model class
21 22 23 |
# File 'lib/rbdantic/json_schema/generator.rb', line 21 def self.generate(model_class, **) new(model_class, **).generate end |
Instance Method Details
#generate ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/rbdantic/json_schema/generator.rb', line 38 def generate # Handle circular references - if being processed, return $ref if @defs_registry && @defs_registry.being_processed?(@model_class) return @defs_registry.ref_for(@model_class) end schema = {} # Only add $schema and $id at top level if @top_level schema["$schema"] = SCHEMA_VERSION schema["$id"] = @schema_id if @schema_id end schema["type"] = "object" # Add optional metadata schema["title"] = @title if @title && @top_level schema["description"] = @description if @description # Mark as being processed before processing fields (for cycle detection) if @defs_registry @defs_registry.mark_processing(@model_class) end # Generate properties properties = {} required = [] @model_class.fields.each do |name, field_info| property_name = schema_property_name(name, field_info) properties[property_name] = generate_property(field_info) required << property_name if field_info.required? end schema["properties"] = properties schema["required"] = required if required.any? # Create a copy of schema for $defs (without $defs key to avoid circular JSON) defs_schema = { "type" => "object", "title" => @title, "description" => @description, "properties" => properties }.compact defs_schema["required"] = required if required.any? # Register this model's schema in defs registry if @defs_registry @defs_registry.register(@model_class, defs_schema) end # Add $defs at top level if we have referenced models if @top_level && @defs_registry defs = if @defs_registry.referenced?(@model_class) @defs_registry.defs_hash else @defs_registry.defs_hash(except: @model_class) end if defs && defs.any? schema["$defs"] = defs end end schema end |