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