blob: 6ed34f3d6f94ce00d67f845e4f7af743f4f8d705 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
module Hashie
module Extensions
# Searches a deeply nested datastructure for a key path, and returns the associated value.
#
# options = { user: { location: { address: '123 Street' } } }
# options.deep_fetch :user, :location, :address #=> '123 Street'
#
# If a block is provided its value will be returned if the key does not exist.
#
# options.deep_fetch(:user, :non_existent_key) { 'a value' } #=> 'a value'
#
# This is particularly useful for fetching values from deeply nested api responses or params hashes.
module DeepFetch
class UndefinedPathError < StandardError; end
def deep_fetch(*args, &block)
args.reduce(self) do |obj, arg|
begin
arg = Integer(arg) if obj.is_a? Array
obj.fetch(arg)
rescue ArgumentError, IndexError, NoMethodError => e
break yield(arg) if block
raise UndefinedPathError, "Could not fetch path (#{args.join(' > ')}) at #{arg}", e.backtrace
end
end
end
end
end
end
|