Class: ApiBee::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/api_bee/node.rb

Overview

API response objects

A node wraps Hash data returned by adapter.get(path) It inspects the returned data and tries to add lazy-loading of missing attributes (provided there is an :href attribute) and pagination (see Node::List)

Direct Known Subclasses

List, Single

Defined Under Namespace

Classes: List, Single

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter, config, attrs, href) ⇒ Node

Returns a new instance of Node.



45
46
47
48
49
50
51
# File 'lib/api_bee/node.rb', line 45

def initialize(adapter, config, attrs, href)
  @adapter = adapter
  @config = config
  @attributes = {}
  @href = href
  update_attributes attrs
end

Instance Attribute Details

#adapterObject (readonly)

Returns the value of attribute adapter.



43
44
45
# File 'lib/api_bee/node.rb', line 43

def adapter
  @adapter
end

Class Method Details

.resolve(adapter, config, attrs, attribute_name = nil) ⇒ Object

Factory. Inspect passed attribute hash for pagination fields and reurns one of Node::List for paginated node lists or Node::Single for single nodes A node (list or single) may contain nested lists or single nodes. This is handled transparently by calling Node.resolve when accessing nested attributes of a node.

Example:

node = Node.resolve(an_adapter, config_object, {:total_entries => 10, :href => '/products', :entries => [...]})
# node is a Node::List because is has pagination fields

node = Node.resolve(an_adapter, config_object, {:name => 'Ismael', :bday => '11/29/77'})
# node is a Node::Single because it doesn't represent a paginated list


31
32
33
34
35
36
37
38
39
40
41
# File 'lib/api_bee/node.rb', line 31

def self.resolve(adapter, config, attrs, attribute_name = nil)
  attrs = simbolized(attrs)
  keys = attrs.keys.map{|k| k.to_sym}
  if keys.include?(config.total_entries_property_name) && keys.include?(config.uri_property_name.to_sym) # is a paginator
    List.new adapter, config, attrs, attribute_name
  else
    node = Single.new adapter, config, attrs, attribute_name
    node = adapter.wrap(node, attribute_name) if adapter.respond_to?(:wrap)
    node      
  end
end

.simbolized(hash) ⇒ Object



11
12
13
14
15
16
# File 'lib/api_bee/node.rb', line 11

def self.simbolized(hash)
  hash.inject({}) do |options, (key, value)|
    options[(key.to_sym rescue key) || key] = value
    options
  end
end

Instance Method Details

#[](attribute_name) ⇒ Object

Lazy loading attribute accessor. Attempts to look for an attribute in this node’s present attributes If the attribute is missing and the node has a :href attribute pointing to more data for this resource it will delegate to the adapter for more data, update it’s attributes and return the found value, if any

Example:

data = {
  :href => '/products/6',
  :title => 'Ipod'
}

node = Node.resolve(adapter, config, data)

node[:title] # => 'Ipod'. 

node[:price] # new request to /products/6


75
76
77
78
79
80
81
82
83
84
# File 'lib/api_bee/node.rb', line 75

def [](attribute_name)
  if value = @attributes[attribute_name]
    resolve_values_to_nodes value, attribute_name
  elsif has_more? # check whether there's more info in API
    load_more!
    self[attribute_name] # recurse once
  else
    nil
  end
end

#[]=(key, value) ⇒ Object



86
87
88
# File 'lib/api_bee/node.rb', line 86

def []=(key, value)
  @attributes[key.to_sym] = value
end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
93
94
# File 'lib/api_bee/node.rb', line 90

def has_key?(key)
  return true if @attributes.has_key? key
  load_more! if has_more?
  @attributes.has_key? key
end

#to_dataObject



53
54
55
# File 'lib/api_bee/node.rb', line 53

def to_data
  @attributes
end