Class: Kabk::Validator

Inherits:
Object
  • Object
show all
Defined in:
lib/kabk/validator.rb

Overview

Handles input sanitization (strong parameters) and validation

Class Method Summary collapse

Class Method Details

.validate_and_sanitize!(resource, params, is_update: false) ⇒ Hash

Sanitizes input parameters against defined fields and validates them

Parameters:

  • resource (Kabk::Resource)
  • params (Hash)

    Request payload

  • is_update (Boolean) (defaults to: false)

    Is this a PUT/update request?

Returns:

  • (Hash)

    Sanitized parameters ready for Sequel

Raises:



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
# File 'lib/kabk/validator.rb', line 13

def self.validate_and_sanitize!(resource, params, is_update: false)
  sanitized = {}
  errors = {}

  # Iterate through all non-readonly fields defined in the schema
  resource.fields.each do |field|
    next if field.primary_key || field.readonly

  # Validate required fields, ignoring absent fields on update.

    key_sym = field.name.to_sym
    key_str = field.name.to_s
    has_key = params.key?(key_sym) || params.key?(key_str)
    value = params[key_sym] || params[key_str]

    if field.required && !has_key && !is_update
      errors[key_str] = ["This field is required"]
      next
    end

    next unless has_key

    if value.nil? || value.to_s.strip.empty?
      if field.required
        errors[key_str] = ["This field is required"]
      end
    end

    # Validate min/max length
    if field.validation && field.type == "string" && value.is_a?(String)
      min_len = field.validation[:min_length] || field.validation["min_length"]
      max_len = field.validation[:max_length] || field.validation["max_length"]

      errors[key_str] = ["Minimum length is #{min_len}"] if min_len && value.length < min_len
      errors[key_str] = ["Maximum length is #{max_len}"] if max_len && value.length > max_len
    end

    sanitized[key_sym] = value
  end

  # Ensure the concurrency field is included for OCC validation.
  if resource.concurrency_field
    c_field = resource.concurrency_field
    sanitized[c_field.to_sym] = params[c_field.to_sym] || params[c_field.to_s] if params.key?(c_field.to_sym) || params.key?(c_field.to_s)
  end

  raise ValidationError.new(fields: errors) unless errors.empty?

  sanitized
end