Class: EasyTalk::ValidationAdapters::Base

Inherits:
Object
  • Object
show all
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.

Examples:

Creating a custom adapter

class MyCustomAdapter < EasyTalk::ValidationAdapters::Base
  def apply_validations
    # Apply custom validations to @klass based on @constraints
    @klass.validates @property_name, presence: true unless optional?
  end
end

Registering and using a custom adapter

EasyTalk::ValidationAdapters::Registry.register(:custom, MyCustomAdapter)

class User
  include EasyTalk::Model
  define_schema(validations: :custom) do
    property :name, String
  end
end

Direct Known Subclasses

ActiveModelAdapter, NoneAdapter

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, property_name, type, constraints) ⇒ Base

Initialize a new validation adapter instance.

Parameters:

  • klass (Class)

    The model class to apply validations to

  • property_name (Symbol, String)

    The name of the property

  • type (Class, Object)

    The type of the property

  • constraints (Hash)

    The JSON Schema constraints for the property



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

#constraintsObject (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

#klassObject (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_nameObject (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

#typeObject (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.

Parameters:

  • klass (Class)

    The model class to apply validations to

  • schema (Hash)

    The full schema hash containing schema-level constraints



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.

Parameters:

  • klass (Class)

    The model class to apply validations to

  • property_name (Symbol, String)

    The name of the property

  • type (Class, Object)

    The type of the property (Ruby class or Sorbet type)

  • constraints (Hash)

    The JSON Schema constraints for the property Possible keys: :min_length, :max_length, :minimum, :maximum, :pattern, :format, :enum, :const, :min_items, :max_items, :unique_items, :optional



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 is abstract.

This method returns an undefined value.

Apply validations based on property type and constraints. Subclasses MUST implement this method.

Raises:

  • (NotImplementedError)

    if the subclass does not 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]). Delegates to TypeIntrospection.

Parameters:

  • type_to_unwrap (Class, Object) (defaults to: @type)

    The type to unwrap (defaults to @type)

Returns:

  • (Class, Object)

    The inner type, or the original type if not wrapped



110
111
112
# File 'lib/easy_talk/validation_adapters/base.rb', line 110

def extract_inner_type(type_to_unwrap = @type)
  TypeIntrospection.extract_inner_type(type_to_unwrap)
end

#get_type_class(type_to_resolve) ⇒ Class+ (protected)

Determine the actual class for a type, handling Sorbet types. Delegates to TypeIntrospection.

Parameters:

  • type_to_resolve (Class, Object)

    The type to resolve

Returns:

  • (Class, Array<Class>)

    The resolved class or classes



119
120
121
# File 'lib/easy_talk/validation_adapters/base.rb', line 119

def get_type_class(type_to_resolve)
  TypeIntrospection.get_type_class(type_to_resolve)
end

#nilable_type?(type_to_check = @type) ⇒ Boolean (protected)

Check if the type is nilable (e.g., T.nilable(String)). Delegates to TypeIntrospection.

Parameters:

  • type_to_check (Class, Object) (defaults to: @type)

    The type to check (defaults to @type)

Returns:

  • (Boolean)

    true if the type is nilable



101
102
103
# File 'lib/easy_talk/validation_adapters/base.rb', line 101

def nilable_type?(type_to_check = @type)
  TypeIntrospection.nilable_type?(type_to_check)
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

Returns:

  • (Boolean)

    true if the property is optional



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