Module: Ask::Schema::DSL::Conditionals

Included in:
Ask::Schema::DSL
Defined in:
lib/ask/schema/dsl/conditionals.rb

Overview

Conditional schema features: if/then/else, dependentRequired, and dependentSchemas for JSON Schema conditional validation.

Instance Method Summary collapse

Instance Method Details

#conditionsArray<Hash>

Collection of conditionals (if/then/else) defined on this schema.

Returns:

  • (Array<Hash>)

    The conditions



11
12
13
# File 'lib/ask/schema/dsl/conditionals.rb', line 11

def conditions
  @conditions ||= []
end

#dependenciesHash{String => ConditionalBuilder}

Collection of dependencies (dependentRequired/dependentSchemas) defined.

Returns:



17
18
19
# File 'lib/ask/schema/dsl/conditionals.rb', line 17

def dependencies
  @dependencies ||= {}
end

#dependent(property, &block) ⇒ Object

Declare that a property has dependencies on other properties.

Examples:

dependent :shipping_address do
  requires :name, :street, :city
end

Parameters:

  • property (Symbol)

    The property that has dependencies

  • block (Proc)

    Block declaring requirements via requires and validates



30
31
32
33
34
35
# File 'lib/ask/schema/dsl/conditionals.rb', line 30

def dependent(property, &block)
  builder = ConditionalBuilder.new
  builder.instance_eval(&block)

  dependencies[property.to_s] = builder
end

#given(**properties, &block) ⇒ Object

Declare a conditional (if/then/else) constraint.

Values are automatically coerced: scalars become const, arrays become enum, and Regexps become pattern.

Examples:

given(age: 18) do
  requires :license_number
  otherwise do
    requires :guardian_name
  end
end

Parameters:

  • properties (Hash{Symbol => Object})

    Property conditions

  • block (Proc)

    Block declaring then/else requirements

Raises:

  • (ArgumentError)

    If no conditions are provided



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/ask/schema/dsl/conditionals.rb', line 53

def given(**properties, &block)
  raise ArgumentError, "given requires at least one property condition" if properties.empty?

  if_schema = {
    properties: properties.transform_keys(&:to_s).transform_values { |v| coerce_condition(v) },
    required: properties.keys.map(&:to_s)
  }

  then_builder = ConditionalBuilder.new
  else_builder = ConditionalBuilder.new

  context = ConditionalContext.new(then_builder, else_builder)
  context.instance_eval(&block)

  condition = {if: if_schema, then: then_builder.to_schema}
  condition[:else] = else_builder.to_schema unless else_builder.empty?

  conditions << condition
end