Class: EasyTalk::ValidationAdapters::Base
- Inherits:
-
Object
- Object
- EasyTalk::ValidationAdapters::Base
- Defined in:
- lib/easy_talk/validation_adapters/base.rb
Overview
Abstract base class for validation adapters.
Validation adapters are responsible for converting JSON Schema constraints into validation rules for the target validation framework (e.g., ActiveModel, dry-validation, or custom validators).
To create a custom adapter, subclass this class and implement the
apply_validations method.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#constraints ⇒ Object
readonly
protected
Returns the value of attribute constraints.
-
#klass ⇒ Object
readonly
protected
Returns the value of attribute klass.
-
#property_name ⇒ Object
readonly
protected
Returns the value of attribute property_name.
-
#type ⇒ Object
readonly
protected
Returns the value of attribute type.
Class Method Summary collapse
-
.build_schema_validations(klass, schema)
Build schema-level validations (e.g., min_properties, max_properties, dependent_required).
-
.build_validations(klass, property_name, type, constraints)
Build validations for a property and apply them to the model class.
Instance Method Summary collapse
-
#apply_validations
abstract
Apply validations based on property type and constraints.
-
#extract_inner_type(type_to_unwrap = @type) ⇒ Class, Object
protected
Extract the inner type from a complex type like T.nilable(String) or T.nilable(T::Array[Model]).
-
#get_type_class(type_to_resolve) ⇒ Class+
protected
Determine the actual class for a type, handling Sorbet types.
-
#initialize(klass, property_name, type, constraints) ⇒ Base
constructor
Initialize a new validation adapter instance.
-
#nilable_type?(type_to_check = @type) ⇒ Boolean
protected
Check if the type is nilable (e.g., T.nilable(String)).
-
#optional? ⇒ Boolean
protected
Check if a property is optional based on constraints and configuration.
Constructor Details
#initialize(klass, property_name, type, constraints) ⇒ Base
Initialize a new validation adapter instance.
63 64 65 66 67 68 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 63 def initialize(klass, property_name, type, constraints) @klass = klass @property_name = property_name.to_sym @type = type @constraints = constraints || {} end |
Instance Attribute Details
#constraints ⇒ Object (readonly, protected)
Returns the value of attribute constraints.
82 83 84 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 82 def constraints @constraints end |
#klass ⇒ Object (readonly, protected)
Returns the value of attribute klass.
82 83 84 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 82 def klass @klass end |
#property_name ⇒ Object (readonly, protected)
Returns the value of attribute property_name.
82 83 84 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 82 def property_name @property_name end |
#type ⇒ Object (readonly, protected)
Returns the value of attribute type.
82 83 84 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 82 def type @type end |
Class Method Details
.build_schema_validations(klass, schema)
This method returns an undefined value.
Build schema-level validations (e.g., min_properties, max_properties, dependent_required). Subclasses can override this method to implement schema-level validations.
53 54 55 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 53 def self.build_schema_validations(klass, schema) # Default implementation does nothing - subclasses can override end |
.build_validations(klass, property_name, type, constraints)
This method returns an undefined value.
Build validations for a property and apply them to the model class. This is the primary interface that adapters must implement.
43 44 45 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 43 def self.build_validations(klass, property_name, type, constraints) new(klass, property_name, type, constraints).apply_validations end |
Instance Method Details
#apply_validations
This method returns an undefined value.
Apply validations based on property type and constraints. Subclasses MUST implement this method.
76 77 78 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 76 def apply_validations raise NotImplementedError, "#{self.class} must implement #apply_validations" end |
#extract_inner_type(type_to_unwrap = @type) ⇒ Class, Object (protected)
Extract the inner type from a complex type like T.nilable(String) or T.nilable(T::Array[Model]).
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 108 def extract_inner_type(type_to_unwrap = @type) if type_to_unwrap.respond_to?(:unwrap_nilable) unwrapped = type_to_unwrap.unwrap_nilable # Return TypedArray directly (for T.nilable(T::Array[Model])) return unwrapped if unwrapped.is_a?(T::Types::TypedArray) # Return raw_type for simple types (for T.nilable(String)) return unwrapped.raw_type if unwrapped.respond_to?(:raw_type) end if type_to_unwrap.respond_to?(:types) # For union types, find the non-nil type # Prefer TypedArray if present, otherwise find type with raw_type type_to_unwrap.types.find { |t| t.is_a?(T::Types::TypedArray) } || type_to_unwrap.types.find { |t| t.respond_to?(:raw_type) && t.raw_type != NilClass } else type_to_unwrap end end |
#get_type_class(type_to_resolve) ⇒ Class+ (protected)
Determine the actual class for a type, handling Sorbet types.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 131 def get_type_class(type_to_resolve) if type_to_resolve.is_a?(Class) type_to_resolve elsif type_to_resolve.respond_to?(:raw_type) type_to_resolve.raw_type elsif type_to_resolve.is_a?(T::Types::TypedArray) Array elsif type_to_resolve.is_a?(EasyTalk::Types::Tuple) Array elsif type_to_resolve.is_a?(Symbol) || type_to_resolve.is_a?(String) begin type_to_resolve.to_s.classify.constantize rescue StandardError String end elsif TypeIntrospection.boolean_type?(type_to_resolve) [TrueClass, FalseClass] elsif nilable_type?(type_to_resolve) extract_inner_type(type_to_resolve) else String end end |
#nilable_type?(type_to_check = @type) ⇒ Boolean (protected)
Check if the type is nilable (e.g., T.nilable(String)).
100 101 102 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 100 def nilable_type?(type_to_check = @type) type_to_check.respond_to?(:nilable?) && type_to_check.nilable? end |
#optional? ⇒ Boolean (protected)
Check if a property is optional based on constraints and configuration.
A property is considered optional if:
- The :optional constraint is explicitly set to true
- The type is nilable AND nilable_is_optional configuration is true
91 92 93 94 |
# File 'lib/easy_talk/validation_adapters/base.rb', line 91 def optional? @constraints[:optional] == true || (@type.respond_to?(:nilable?) && @type.nilable? && EasyTalk.configuration.nilable_is_optional) end |