class RSchema::Coercers::FixedHash::DefaultArraysToEmpty

The HTTP standard says that when a form is submitted, all unchecked check boxes will not be sent to the server. That is, they will not be present at all in the params hash.

This class coerces these missing values into an empty array, where an array is expected.

Attributes

hash_attributes[R]

Public Class Methods

build(schema) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb, line 17
def self.build(schema)
  new(schema)
end
new(fixed_hash_schema) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb, line 21
def initialize(fixed_hash_schema)
  # TODO: make fixed hash attributes frozen, and eliminate dup
  @hash_attributes = fixed_hash_schema.attributes.map(&:dup)
end

Public Instance Methods

call(value) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb, line 26
def call(value)
  Result.success(default_arrays_to_empty(value))
end
will_affect?(value) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb, line 30
def will_affect?(value)
  keys_to_default(value).any?
end

Private Instance Methods

array_schema?(schema) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb, line 64
def array_schema?(schema)
  # dig through all the coercers
  non_coercer = schema
  while non_coercer.is_a?(Schemas::Coercer)
    non_coercer = non_coercer.subschema
  end

  non_coercer.is_a?(Schemas::VariableLengthArray)
end
default_arrays_to_empty(hash) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb, line 36
def default_arrays_to_empty(hash)
  missing_keys = keys_to_default(hash)

  if missing_keys.any?
    defaults = missing_keys.map { |k| [k, []] }.to_h
    hash.merge(defaults)
  else
    hash # no coercion necessary
  end
end
keys_for_array_defaulting() click to toggle source
# File lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb, line 55
def keys_for_array_defaulting
  @keys_for_array_defaulting ||= Set.new(
    hash_attributes
      .reject(&:optional)
      .select { |attr| array_schema?(attr.value_schema) }
      .map(&:key),
  )
end
keys_to_default(value) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_arrays_to_empty.rb, line 47
def keys_to_default(value)
  if value.is_a?(Hash)
    keys_for_array_defaulting - value.keys
  else
    []
  end
end