Class: CloudSpokes::Model::BaseApi

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Model
Defined in:
app/models/cloud_spokes/model/base_api.rb

Direct Known Subclasses

Category, Challenge, Member

Constant Summary collapse

ENDPOINT_EXPIRY =
ENV['CS_API_EXPIRY'].to_i || CloudSpokes::APP_CONFIG[:expiry]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ActiveModel::Model

included

Constructor Details

#initialize(params = {}) ⇒ BaseApi

Wrap initialize with a sanitation clause



76
77
78
79
80
81
# File 'app/models/cloud_spokes/model/base_api.rb', line 76

def initialize(params={})
  Rails.logger.info "=====calling init with #{params}"
  @raw_data = params.dup
  params.delete_if {|k, v| !self.class.column_names.include? k.to_sym}
  super(params)
end

Class Method Details

.allObject

Returns all the records from the CloudSpokes API



57
58
59
# File 'app/models/cloud_spokes/model/base_api.rb', line 57

def self.all
  request(:get, '', {}).map {|item| new item}
end

.api_endpointObject

Returns the api_endpoint. Note that you need to implement this method in the child object



52
53
54
# File 'app/models/cloud_spokes/model/base_api.rb', line 52

def self.api_endpoint
  raise 'Please implement ::api_endpoint in the child object'
end

.api_request_headersObject



114
115
116
117
118
119
120
# File 'app/models/cloud_spokes/model/base_api.rb', line 114

def self.api_request_headers
  {
    'oauth_token' => access_token,
    'Authorization' => 'Token token="'+(ENV['CS_API_KEY']|| CloudSpokes::APP_CONFIG[:cs_api][:key])+'"',
    'Content-Type' => 'application/json'
  }
end

.attr_accessor(*vars) ⇒ Object

Overrides the attr_accesssor class method so we are able to capture and then save the defined fields as column_names



35
36
37
38
39
# File 'app/models/cloud_spokes/model/base_api.rb', line 35

def self.attr_accessor(*vars)
  @column_names ||= []
  @column_names.concat( vars )
  super
end

.column_namesObject

Returns the previously defined attr_accessor fields



42
43
44
# File 'app/models/cloud_spokes/model/base_api.rb', line 42

def self.column_names
  @column_names
end

.create(attrs) ⇒ Object



108
109
110
111
112
# File 'app/models/cloud_spokes/model/base_api.rb', line 108

def self.create(attrs)
  obj = new(attrs)
  obj.save
  obj
end

.endpoint_from_entities(entities = []) ⇒ Object



139
140
141
142
# File 'app/models/cloud_spokes/model/base_api.rb', line 139

def self.endpoint_from_entities(entities = [])
  entities = entities.respond_to?(:join) ? entities.join("/") : entities.to_s
  entities.present? ? "#{api_endpoint}/#{entities}" : api_endpoint
end

.find(entity) ⇒ Object

Finds an entity



69
70
71
72
73
# File 'app/models/cloud_spokes/model/base_api.rb', line 69

def self.find(entity)
  Rails.logger.info "========== running find for #{entity} for #{self.name}"
  c = self.name.to_s.split("::").inject(Object) { |n,c| n.const_get c }
  c.new(raw_get entity)
end

.firstObject

Returns the first record TODO: when the API supports it, simply request for the first record. There should be no need to request for all the records first.



64
65
66
# File 'app/models/cloud_spokes/model/base_api.rb', line 64

def self.first
  all.first
end

.get(entity = '') ⇒ Object

Sanitized response to only the attributes we’ve defined



135
136
137
# File 'app/models/cloud_spokes/model/base_api.rb', line 135

def self.get(entity = '')
  raw_get(entity).delete_if {|k, v| !column_names.include? k.to_sym}
end

.get_response(data) ⇒ Object



144
145
146
# File 'app/models/cloud_spokes/model/base_api.rb', line 144

def self.get_response(data)
  Hashie::Mash.new(JSON.parse(data)).response
end

.has_many(entity, options = {}) ⇒ Object

Implements the has_many relationship Passing :parent as an option allows modification of the calling class This is used mostly for has and belongs to many relationships, where a model collection will have a different endpoint Case in point: Members and Challenges



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'app/models/cloud_spokes/model/base_api.rb', line 13

def self.has_many(entity, options={})
  # add in this relationship to the column_names table
  @column_names << entity.to_sym
  rel_column_names << entity.to_sym
  parent = options[:parent]

  # dynamically create a method on this instance that will reference the collection
  define_method("#{entity.to_sym}=") do |accessor_value|
    instance_variable_set("@#{entity.to_sym}", accessor_value)
  end

  define_method(entity.to_sym) do
    klass = entity.to_s.classify.constantize
    (parent || klass).raw_get([to_param, entity.to_s]).map do |e|
      next if e.respond_to?(:last) # we got an array instead of a Hashie::Mash
      klass.new e
    end
  end
end

.post(entities, data) ⇒ Object



163
164
165
# File 'app/models/cloud_spokes/model/base_api.rb', line 163

def self.post(entities, data)
  request :post, entities, data
end

.put(entities, data) ⇒ Object



167
168
169
# File 'app/models/cloud_spokes/model/base_api.rb', line 167

def self.put(entities, data)
  request :put, entities, data
end

.raw_get(entities = []) ⇒ Object

Convenience method to request an entity from the CloudSpokes RESTful source Accepts an array or a string If given an array, will join the elements with ‘/’ If given a string, will use the argument as is



126
127
128
129
130
131
132
# File 'app/models/cloud_spokes/model/base_api.rb', line 126

def self.raw_get(entities = [])
  endpoint = endpoint_from_entities(entities)
  Rails.logger.info "=====$$$$$ CALLING RAW GET #{entities} for #{endpoint}"
  #Rails.cache.fetch("#{endpoint}", expires_in: ENDPOINT_EXPIRY.minutes) do
    get_response(RestClient.get(endpoint, api_request_headers))
  #end
end

.rel_column_namesObject



46
47
48
# File 'app/models/cloud_spokes/model/base_api.rb', line 46

def self.rel_column_names
  @rel_column_names ||= []
end

.request(method, entities, data) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'app/models/cloud_spokes/model/base_api.rb', line 148

def self.request(method, entities, data)
  Rails.logger.info "===== access_token: #{access_token}"
  Rails.logger.info "===== method: #{method}"
  endpoint = endpoint_from_entities(entities)
  Rails.logger.info "===== endpoint: #{endpoint}"
  if method.to_sym == :get
    endpoint += "?#{data.to_param}"
    resp = RestClient.send method, endpoint, api_request_headers
  else
    data = data.to_json unless data.is_a?(String)
    resp = RestClient.send method, endpoint, data, api_request_headers
  end
  get_response(resp)
end

Instance Method Details

#new_record?Boolean

Returns:

  • (Boolean)


104
105
106
# File 'app/models/cloud_spokes/model/base_api.rb', line 104

def new_record?
  id.blank?
end

#persisted?Boolean

Returns if this record has the id attribute set (used by url_for for routing)

Returns:

  • (Boolean)


89
90
91
# File 'app/models/cloud_spokes/model/base_api.rb', line 89

def persisted?
  !!id
end

#raw_dataObject

Returns the raw data that created this object



84
85
86
# File 'app/models/cloud_spokes/model/base_api.rb', line 84

def raw_data
  @raw_data
end

#saveObject



93
94
95
# File 'app/models/cloud_spokes/model/base_api.rb', line 93

def save
  new_record? ? create : update
end

#update_attributes(attrs = {}) ⇒ Object



97
98
99
100
101
102
# File 'app/models/cloud_spokes/model/base_api.rb', line 97

def update_attributes(attrs={})
  attrs.each do |attr, value|
    self.public_send("#{attr}=", value)
  end
  save
end