class SmartParams::Field
Attributes
keychain[R]
subfields[R]
type[R]
Public Class Methods
new(keychain:, type:, nullable: false, &nesting)
click to toggle source
# File lib/smart_params/field.rb, line 7 def initialize(keychain:, type:, nullable: false, &nesting) @keychain = Array(keychain) @subfields = Set.new @type = type @nullable = nullable @specified = false @dirty = false if block_given? instance_eval(&nesting) end end
Public Instance Methods
allow_empty?()
click to toggle source
Check if we should consider this value even when empty.
# File lib/smart_params/field.rb, line 61 def allow_empty? return true if specified? && nullable? return subfields.select(&:allow_empty?).any? false end
claim(raw)
click to toggle source
# File lib/smart_params/field.rb, line 67 def claim(raw) return type[dug(raw)] if deep? @value = type[dug(raw)] rescue Dry::Types::ConstraintError => bad_type_exception raise SmartParams::Error::InvalidPropertyType, keychain: keychain, wanted: type, raw: if keychain.empty? then raw else raw.dig(*keychain) end end
clean?()
click to toggle source
# File lib/smart_params/field.rb, line 54 def clean? return false if dirty? return true if empty? || subfields.select { |sub| !sub.empty? }.any? false end
deep?()
click to toggle source
# File lib/smart_params/field.rb, line 20 def deep? # We check @specified directly because we want to know if ANY # subfields have been passed, not just ones that match the schema. return false if nullable? && !!@specified subfields.present? end
dirty?()
click to toggle source
For nullable hashes: Any keys not in the schema make the hash dirty. If a key is found that matches the schema, we can consider the hash clean.
# File lib/smart_params/field.rb, line 50 def dirty? !!@dirty end
empty?()
click to toggle source
# File lib/smart_params/field.rb, line 81 def empty? value.nil? end
nullable?()
click to toggle source
# File lib/smart_params/field.rb, line 35 def nullable? !!@nullable end
removable?()
click to toggle source
Should this field be removed from resulting hash?
# File lib/smart_params/field.rb, line 86 def removable? empty? && !allow_empty? end
root?()
click to toggle source
# File lib/smart_params/field.rb, line 27 def root? keychain.size == 0 end
specified?()
click to toggle source
# File lib/smart_params/field.rb, line 39 def specified? if nullable? !!@specified && clean? else !!@specified end end
to_hash()
click to toggle source
# File lib/smart_params/field.rb, line 75 def to_hash keychain.reverse.reduce(value) do |accumulation, key| { key => accumulation } end end
value()
click to toggle source
# File lib/smart_params/field.rb, line 31 def value @value || ({} if root?) end
weight()
click to toggle source
# File lib/smart_params/field.rb, line 90 def weight keychain.map(&:to_s) end
Private Instance Methods
dug(raw)
click to toggle source
Very busy method with recent changes. TODO: clean-up
# File lib/smart_params/field.rb, line 102 def dug(raw) return raw if keychain.empty? # If value provided is a hash, check if it's dirty. See #dirty? for # more info. if nullable? hash = raw.dig(*keychain) if hash.respond_to?(:keys) others = hash.keys - [keychain.last] @dirty = others.any? end end # Trace the keychain to find out if the field is explicitly set in the # input hash. at = raw exact = true keychain.each { |key| if at.respond_to?(:key?) && at.key?(key) at = at[key] else exact = false break end } @specified = exact raw.dig(*keychain) end
field(key, type:, nullable: false, &subfield)
click to toggle source
# File lib/smart_params/field.rb, line 94 def field(key, type:, nullable: false, &subfield) if nullable type |= SmartParams::Strict::Nil end @subfields << self.class.new(keychain: [*keychain, key], type: type, nullable: nullable, &subfield) end