lib/metaractor/errors.rb in metaractor-3.1.1 vs lib/metaractor/errors.rb in metaractor-3.2.0

- old
+ new

@@ -69,22 +69,23 @@ def_delegators :@tree, :empty? def add(error: {}, errors: {}, object: nil) trees = [] - [error, errors].each do |h| + [error, errors].each do |h| tree = nil if h.is_a? Metaractor::Errors tree = Sycamore::Tree.from(h.instance_variable_get(:@tree)) else - tree = Sycamore::Tree.from(h) + tree = Sycamore::Tree.from(normalize_error_hash(h)) end unless tree.empty? - if tree.nodes.any? {|node| tree.strict_leaf?(node) } + if tree.nodes.any? { |node| tree.strict_leaf?(node) } raise ArgumentError, "Invalid hash!" end + trees << tree end end trees.each do |tree| @@ -218,7 +219,36 @@ element end end end + def normalize_error_hash(hash) + deep_transform_values_in_object(hash, &method(:transform_delegator)) + end + + def transform_delegator(value) + if value.is_a?(Delegator) + if value.respond_to?(:to_hash) + deep_transform_values_in_object(value.to_hash, &method(:transform_delegator)) + elsif value.respond_to?(:to_a) + deep_transform_values_in_object(value.to_a, &method(:transform_delegator)) + else + value + end + else + value + end + end + + # Lifted from Rails + def deep_transform_values_in_object(object, &block) + case object + when Hash + object.transform_values { |value| deep_transform_values_in_object(value, &block) } + when Array + object.map { |e| deep_transform_values_in_object(e, &block) } + else + yield(object) + end + end end end