Class: ApiResource::Resource

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Model, ActiveModel::Serializers::JSON
Defined in:
lib/api-resource/resource.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash = nil) ⇒ Resource

Returns a new instance of Resource.



43
44
45
# File 'lib/api-resource/resource.rb', line 43

def initialize(hash=nil)
  self.attributes = hash if hash
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &_) ⇒ Object (protected)



174
175
176
177
178
179
180
181
182
# File 'lib/api-resource/resource.rb', line 174

def method_missing(m, *args, &_)
  case m
    when /^by_(.+)/
      self.resource_path = self.class.build_url($1.pluralize, args[0], resource_path)
      self
    else
      super
  end
end

Class Method Details

.allObject



69
70
71
# File 'lib/api-resource/resource.rb', line 69

def self.all
  self.where({})
end

.all_pages(params = {}) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/api-resource/resource.rb', line 73

def self.all_pages(params={})
  params  = { page: 1, per_page: default_per_page }.merge(params)
  per_page = params[:per_page].to_i
  page     = params[:page].to_i
  begin
    params[:page] = page
    result         = self.where(params)
    total_count    = result.try :total_count
    arr            = result.to_a
    count          = arr.length
    break if yield(arr, page, per_page, total_count) || (page - 1) * per_page + count >= total_count
    page += 1
  end while true
end

.build_url(*paths) ⇒ Object

Raises:

  • (RuntimeError)


241
242
243
244
# File 'lib/api-resource/resource.rb', line 241

def self.build_url(*paths)
  raise RuntimeError, 'Empty base_url' if base_url.blank?
  URI::parse(base_url).merge(paths.map { |p| "#{URI.encode p.to_s}" }.join('/')).to_s
end

.client(method, params, *paths) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/api-resource/resource.rb', line 222

def self.client(method, params, *paths)
  url        = build_url(*paths)
  headers    = { accept: :json }
  req_params = { url: url, method: method, headers: headers }
  if method == :get
    # using #to_query instead of URI::encode_www_form to comply with rails convention for query string array values
    req_params[:url] = "#{url}?#{params.to_query}" unless params.to_query.blank?
  else
    req_params[:payload] = params
  end
  req = RestClient::Request.new(req_params)
  if hmac
    req.sign!(api_id, api_secret, hmac_options)
  end
  result = req.execute
  log << result
  result
end

.create_log(param) ⇒ Object

Create a log that respond to << like a logger param can be ‘stdout’, ‘stderr’, a string (then we will log to that file) or a logger (then we return it)



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/api-resource/resource.rb', line 259

def self.create_log(param)
  return param unless param.is_a? String
  case param
    when 'stdout'
      Class.new do
        def <<(obj)
          STDOUT.puts obj
        end
      end.new
    when 'stderr'
      Class.new do
        def <<(obj)
          STDERR.puts obj
        end
      end.new
    else
      Class.new do
        def initialize(file)
          @file = file
        end

        def <<(obj)
          File.open(@file, 'a') { |f| f.puts obj }
        end
      end.new(param)
  end
end

.create_resource_collection(result) ⇒ Object



185
186
187
188
# File 'lib/api-resource/resource.rb', line 185

def self.create_resource_collection(result)
  json = JSON.parse(result)
  ResourceCollection.new(json['data'], json['meta'], self)
end

.filter_submitted_attributes(&block) ⇒ Object



39
40
41
# File 'lib/api-resource/resource.rb', line 39

def self.(&block)
  self.pre_submit_filter = block if block_given?
end

.find(id, params = {}) ⇒ Object



63
64
65
66
67
# File 'lib/api-resource/resource.rb', line 63

def self.find(id, params={})
  result = client(:get, params, resource_path, id)
  json   = JSON.parse(result)
  self.new(json['data'] || json)
end

.load_class(tableized_class) ⇒ Object



190
191
192
193
194
# File 'lib/api-resource/resource.rb', line 190

def self.load_class(tableized_class)
  tableized_class = name.to_s.tableize.split('/')[0...-1].push(tableized_class).join('/')
  klass = tableized_class && tableized_class.to_s.singularize.classify.constantize rescue nil
  klass if klass && klass < ApiResource::Resource
end

.logObject



250
251
252
253
254
255
# File 'lib/api-resource/resource.rb', line 250

def self.log
  self.logger ||= Class.new do
    def <<(_)
    end
  end.new
end

.log=(param) ⇒ Object



246
247
248
# File 'lib/api-resource/resource.rb', line 246

def self.log=(param)
  self.logger = create_log(param)
end

.method_missing(m, *args, &_) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
# File 'lib/api-resource/resource.rb', line 162

def self.method_missing(m, *args, &_)
  case (m)
    when /^by_(.+)/
      resource_path = build_url($1.pluralize, args[0], self.resource_path)
      Class.new(self) do
        self.resource_path = resource_path
      end
    else
      super
  end
end

.resource_pathObject



47
48
49
# File 'lib/api-resource/resource.rb', line 47

def self.resource_path
  @resource_path || name.to_s.tableize.split('/').last
end

.resource_path=(path) ⇒ Object



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

def self.resource_path=(path)
  @resource_path = path.gsub(%r{\A/+|/+\Z}, '')
end

.where(params) ⇒ Object



88
89
90
91
# File 'lib/api-resource/resource.rb', line 88

def self.where(params)
  result = client(:get, params, resource_path)
  create_resource_collection(result)
end

.with_hmac(api_id, api_secret, options = {}) ⇒ Object



32
33
34
35
36
37
# File 'lib/api-resource/resource.rb', line 32

def self.with_hmac(api_id, api_secret, options={})
  self.hmac         = true
  self.api_id       = api_id
  self.api_secret   = api_secret
  self.hmac_options = options
end

Instance Method Details

#attributesObject



117
118
119
# File 'lib/api-resource/resource.rb', line 117

def attributes
  instance_values.with_indifferent_access.except(:errors, :validation_context, :resource_path)
end

#destroy!(options = {}) ⇒ Object



112
113
114
115
# File 'lib/api-resource/resource.rb', line 112

def destroy!(options={})
  submit_resource(resource_path, false, options[:id_attr], :delete)
  self
end

#resource_pathObject



55
56
57
# File 'lib/api-resource/resource.rb', line 55

def resource_path
  @resource_path ||= self.class.resource_path
end

#resource_path=(path) ⇒ Object



59
60
61
# File 'lib/api-resource/resource.rb', line 59

def resource_path=(path)
  @resource_path = path
end

#save!(options = {}) ⇒ Object



93
94
95
96
# File 'lib/api-resource/resource.rb', line 93

def save!(options={})
  submit_resource(resource_path, true, options[:id_attr])
  self
end

#submit!(options = {}) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/api-resource/resource.rb', line 98

def submit!(options={})
  path = options.fetch(:path, resource_path)
  type = options[:type]
  json = submit_resource(path, false, options[:id_attr])
  meta = json && json['meta']
  type ||= meta && meta['type']
  if type
    returned_type = self.class.load_class(type)
    returned_type.new(json['data'] || json)
  else
    self
  end
end