Class: ApiQueryProvider::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/api-query-provider/base.rb

Overview

This class serves as a base class for any API Requests, it has several settings: api_url: sets the base url requests are made to_sym api_path: sets the path specific to this class, can contain replaceable elements data_selector: if the data is wrapped in an object, you can define a Proc taking the parsed response as Hash and returning a portion of that Hash for further parsing the keys are Strings. Be aware that if the data contains any fields named like a ruby internal method or field, it will be shadowed if you define it explicitly, it autogeneration is enabled, the name will have a underscore appended.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ Base

basic parsing constructor takes the json data and tries to assign it to attr_accessor methods make sure to define them for any field present in the response



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/api-query-provider/base.rb', line 73

def initialize(data)
  if self.class == ApiQueryProvider::Base
    raise "this class should never be instanciated directly"
  end
  
  @provided_symbols = []

  data.each do |key, value|
    @provided_symbols << key.to_sym
         
    key = self.class.shadow key
  
    if !self.respond_to? key.to_sym
      if self.class.autogenerate
        self.class.class_eval do
          attr_accessor key.to_sym
        end
      else
        raise "field not found: #{key}. Either enable auto generation or add attr_accessor :#{key}"
      end
    end

    if self.class.custom_fields.include? key.to_sym
      value = self.class.custom_fields[key.to_sym].call(value)
    end
    
    self.send("#{key}=".to_sym, value)
  end
end

Instance Attribute Details

#provided_symbolsObject (readonly)

Returns the value of attribute provided_symbols.



67
68
69
# File 'lib/api-query-provider/base.rb', line 67

def provided_symbols
  @provided_symbols
end

Class Method Details

.api_pathObject



21
22
23
# File 'lib/api-query-provider/base.rb', line 21

def self.api_path
  @api_path
end

.api_path=(value) ⇒ Object



25
26
27
# File 'lib/api-query-provider/base.rb', line 25

def self.api_path= (value)
  @api_path = value
end

.api_urlObject



13
14
15
# File 'lib/api-query-provider/base.rb', line 13

def self.api_url
  @api_url
end

.api_url=(value) ⇒ Object



17
18
19
# File 'lib/api-query-provider/base.rb', line 17

def self.api_url= (value)
  @api_url = value
end

.autogenerateObject



41
42
43
44
45
46
47
# File 'lib/api-query-provider/base.rb', line 41

def self.autogenerate
  if @autogenerate.nil?
    false
  else
    @autogenerate
  end
end

.autogenerate=(value) ⇒ Object



49
50
51
# File 'lib/api-query-provider/base.rb', line 49

def self.autogenerate= (value)
  @autogenerate = value
end

.custom_field(field, &block) ⇒ Object



53
54
55
56
57
# File 'lib/api-query-provider/base.rb', line 53

def self.custom_field(field, &block)
  @custom_fields ||= {}
  
  @custom_fields[field.to_sym] = block.to_proc
end

.custom_fieldsObject



59
60
61
# File 'lib/api-query-provider/base.rb', line 59

def self.custom_fields
  @custom_fields || {}
end

.data_selectorObject



33
34
35
# File 'lib/api-query-provider/base.rb', line 33

def self.data_selector
  @data_selector || Proc.new { |e| e }
end

.data_selector=(value) ⇒ Object



37
38
39
# File 'lib/api-query-provider/base.rb', line 37

def self.data_selector= (value)
  @data_selector = value
end

.interfaceObject



136
137
138
# File 'lib/api-query-provider/base.rb', line 136

def self.interface
  ApiQueryProvider::Provider.new(self)
end

.limit(count) ⇒ Object



144
145
146
# File 'lib/api-query-provider/base.rb', line 144

def self.limit(count)
  interface.limit(count)
end

.required_symbolsObject



29
30
31
# File 'lib/api-query-provider/base.rb', line 29

def self.required_symbols
  @api_path.scan(/:(\w+)/).flatten.map { |e| e.to_sym } - ApiQueryProvider::Provider.system_symbols
end

.select(*fields) ⇒ Object



148
149
150
# File 'lib/api-query-provider/base.rb', line 148

def self.select(*fields)
  interface.select(fields)
end

.shadow(key) ⇒ Object



63
64
65
# File 'lib/api-query-provider/base.rb', line 63

def self.shadow(key)
  key.to_sym == :class ? "class_".to_sym : key
end

.where(opt = {}) ⇒ Object



140
141
142
# File 'lib/api-query-provider/base.rb', line 140

def self.where(opt = {})
  interface.where(opt)
end

Instance Method Details

#extendObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/api-query-provider/base.rb', line 103

def extend
  if !(self.class.required_symbols - provided_symbols).empty?
    raise "not all needed values are present"
  end
  
  request = self.class.where
  
  self.class.required_symbols.each do |sym|
    request = request.where(sym => self.send(self.class.shadow(sym).to_sym))
  end
  
  response = request.execute
  
  if response.count != 1
    raise "the request did not return exactly one element"
  end
  
  response.first 
end

#extend!Object



123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/api-query-provider/base.rb', line 123

def extend!
  local = self.extend
  
  local.provided_symbols.each do |symbol|
    shadow = self.class.shadow(symbol).to_sym
    self.send("#{shadow}=".to_sym, local.send("#{shadow}".to_sym))
  end
  
  @provided_symbols = local.provided_symbols
  
  self
end