class RSchema::Coercers::FixedHash::DefaultBooleansToFalse

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 `false`.

Attributes

hash_attributes[R]

Public Class Methods

build(schema) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_booleans_to_false.rb, line 16
def self.build(schema)
  new(schema)
end
new(fixed_hash_schema) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_booleans_to_false.rb, line 20
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_booleans_to_false.rb, line 25
def call(value)
  Result.success(default_bools_to_false(value))
end
will_affect?(value) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_booleans_to_false.rb, line 29
def will_affect?(value)
  keys_to_default(value).any?
end

Private Instance Methods

bool_schema?(schema) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_booleans_to_false.rb, line 63
def bool_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::Boolean)
end
default_bools_to_false(hash) click to toggle source
# File lib/rschema/coercers/fixed_hash/default_booleans_to_false.rb, line 35
def default_bools_to_false(hash)
  missing_keys = keys_to_default(hash)

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