Module: EasyTalk::ValidationAdapters::ActiveModelSchemaValidation

Defined in:
lib/easy_talk/validation_adapters/active_model_schema_validation.rb

Overview

ActiveModel-specific schema-level validations for object-level constraints.

This module provides ActiveModel validations for JSON Schema keywords that apply to the object as a whole rather than individual properties:

  • minProperties: minimum number of properties that must be present
  • maxProperties: maximum number of properties that can be present
  • dependentRequired: conditional property requirements

This module is tightly coupled with ActiveModel and is used exclusively by ActiveModelAdapter. Other validation adapters should implement their own schema-level validation logic.

Class Method Summary collapse

Class Method Details

.apply(klass, schema)

This method returns an undefined value.

Apply all applicable schema-level validations.

Parameters:

  • The model class to apply validations to

  • The full schema hash containing schema-level constraints



23
24
25
26
27
# File 'lib/easy_talk/validation_adapters/active_model_schema_validation.rb', line 23

def self.apply(klass, schema)
  apply_min_properties_validation(klass, schema[:min_properties]) if schema[:min_properties]
  apply_max_properties_validation(klass, schema[:max_properties]) if schema[:max_properties]
  apply_dependent_required_validation(klass, schema[:dependent_required]) if schema[:dependent_required]
end

.apply_dependent_required_validation(klass, dependencies) ⇒ Object

Apply dependent required validation. When a trigger property is present, all dependent properties must also be present.

Parameters:

  • The model class

  • Map of trigger properties to required properties



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/easy_talk/validation_adapters/active_model_schema_validation.rb', line 64

def self.apply_dependent_required_validation(klass, dependencies)
  dependencies.each do |trigger_property, required_properties|
    trigger_prop = trigger_property.to_sym
    required_props = required_properties.map(&:to_sym)

    klass.validate do |record|
      trigger_value = record.public_send(trigger_prop)
      trigger_present = trigger_value.present? || trigger_value == false

      next unless trigger_present

      required_props.each do |required_prop|
        value = record.public_send(required_prop)
        value_present = value.present? || value == false

        record.errors.add(required_prop, "is required when #{trigger_prop} is present") unless value_present
      end
    end
  end
end

.apply_max_properties_validation(klass, max_count) ⇒ Object

Apply maximum properties validation.

Parameters:

  • The model class

  • Maximum number of properties that can be present



48
49
50
51
52
53
54
55
56
57
# File 'lib/easy_talk/validation_adapters/active_model_schema_validation.rb', line 48

def self.apply_max_properties_validation(klass, max_count)
  define_count_method(klass)

  klass.validate do |record|
    present_count = record.send(:count_present_properties)
    if present_count > max_count
      record.errors.add(:base, "must have at most #{max_count} #{max_count == 1 ? 'property' : 'properties'} present")
    end
  end
end

.apply_min_properties_validation(klass, min_count) ⇒ Object

Apply minimum properties validation.

Parameters:

  • The model class

  • Minimum number of properties that must be present



33
34
35
36
37
38
39
40
41
42
# File 'lib/easy_talk/validation_adapters/active_model_schema_validation.rb', line 33

def self.apply_min_properties_validation(klass, min_count)
  define_count_method(klass)

  klass.validate do |record|
    present_count = record.send(:count_present_properties)
    if present_count < min_count
      record.errors.add(:base, "must have at least #{min_count} #{min_count == 1 ? 'property' : 'properties'} present")
    end
  end
end