Class: Veryfi::Resource

Inherits:
Hash
  • Object
show all
Defined in:
lib/veryfi/resource.rb

Overview

A lightweight, dependency-free wrapper around an API response payload.

Resource inherits from Hash, so anything that already treats the response as a hash keeps working unchanged:

response["id"] # => 44691518 response.dig("vendor", "name") response.is_a?(Hash) # => true JSON.pretty_generate(response)

In addition, every key is also accessible as a method, recursively:

response.id # => 44691518 response.vendor.name # => "East Repair" response.line_items.first.description response.is_duplicate? # => truthiness of self["is_duplicate"]

Nested hashes are wrapped into Resources, and arrays of hashes become arrays of Resources. Other values (strings, numbers, booleans, nil) pass through untouched. Both string ("id") and symbol (:id) keys work transparently.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash = {}) ⇒ Resource

Returns a new instance of Resource.



41
42
43
44
# File 'lib/veryfi/resource.rb', line 41

def initialize(hash = {})
  super()
  hash.each_pair { |key, value| self[key.to_s] = Resource.wrap(value) }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/veryfi/resource.rb', line 80

def method_missing(name, *args, &block)
  string_name = name.to_s
  bare_name = string_name.chomp("?")

  if args.empty? && block.nil? && key?(bare_name)
    value = self[bare_name]
    string_name.end_with?("?") ? !value.nil? && value != false : value
  else
    super
  end
end

Class Method Details

.wrap(value) ⇒ Object

Wrap any value coming back from the API. Hashes become Resources, arrays are mapped recursively, and everything else passes through.

Parameters:

  • value (Object)

    raw value from JSON.parse

Returns:

  • (Object)

    wrapped value



31
32
33
34
35
36
37
38
39
# File 'lib/veryfi/resource.rb', line 31

def self.wrap(value)
  return value if value.is_a?(Resource)

  case value
  when ::Hash  then new(value)
  when ::Array then value.map { |v| wrap(v) }
  else              value
  end
end

Instance Method Details

#[](key) ⇒ Object



46
47
48
# File 'lib/veryfi/resource.rb', line 46

def [](key)
  super(key.to_s)
end

#fetch(key, *args, &block) ⇒ Object

rubocop:disable Style/ArgumentsForwarding -- keep explicit forwarding for clarity and Ruby 3.0 portability



51
52
53
# File 'lib/veryfi/resource.rb', line 51

def fetch(key, *args, &block)
  super(key.to_s, *args, &block)
end

#key?(key) ⇒ Boolean Also known as: has_key?, include?, member?

rubocop:enable Style/ArgumentsForwarding

Returns:

  • (Boolean)


56
57
58
# File 'lib/veryfi/resource.rb', line 56

def key?(key)
  super(key.to_s)
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
78
# File 'lib/veryfi/resource.rb', line 75

def respond_to_missing?(name, include_private = false)
  string_name = name.to_s.chomp("?")
  key?(string_name) || super
end

#to_hHash Also known as: to_hash

Returns a plain (unwrapped) Hash representation, recursively. Useful when you need to hand the data off to something that explicitly expects a plain Hash (e.g. some serializers).

Returns:

  • (Hash)


68
69
70
71
72
# File 'lib/veryfi/resource.rb', line 68

def to_h
  each_with_object({}) do |(key, value), memo|
    memo[key] = unwrap(value)
  end
end