Class: Vend::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/vend/base.rb

Overview

This Base class provides the basic mapping between Vend::Resource subclasses and the HTTP endpoints in the Vend API.

Not all CRUD actions are available for every resource, and at current there is no PUT endpoint and hence no update action

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, options = {}) ⇒ Base

:nodoc:



18
19
20
21
# File 'lib/vend/base.rb', line 18

def initialize(client, options = {}) #:nodoc:
  @client = client
  @attrs = options[:attrs] || {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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

Overrides method_missing to query the attrs hash for the value stored at the specified key before proxying it to the object



173
174
175
176
177
178
179
# File 'lib/vend/base.rb', line 173

def method_missing(method_name, *args, &block)
  if attrs.keys.include? method_name.to_s
    attribute_value_for(method_name)
  else
    super(method_name)
  end
end

Instance Attribute Details

#attrsObject

Hash of attributes for this instance. Represents the data returned from the Vend API



16
17
18
# File 'lib/vend/base.rb', line 16

def attrs
  @attrs
end

#clientObject (readonly)

Reference to the Vend::Client client object providing the HTTP interface to the API



12
13
14
# File 'lib/vend/base.rb', line 12

def client
  @client
end

Class Method Details

.accepts_scope?(scope_name) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/vend/base.rb', line 65

def self.accepts_scope?(scope_name)
  available_scopes.include?(scope_name)
end

.all(client) ⇒ Object

Returns a collection containing all of the specified resource objects. Will paginate.



51
52
53
# File 'lib/vend/base.rb', line 51

def self.all(client)
  initialize_collection(client, collection_name)
end

.attribute_castsObject



27
28
29
# File 'lib/vend/base.rb', line 27

def self.attribute_casts
  @attribute_casts ||= {}
end

.available_scopesObject

Returns the list of URL parameter scopes that are available for this resource. For example, if the resource accepted URLs like:

/api/resources/since/YYYY-MM-DD HH:MM:SS/outlet_id/abc-1234-def

this method would return [:since, :outlet_id]



61
62
63
# File 'lib/vend/base.rb', line 61

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

.build(client, attrs) ⇒ Object

Builds a new instance of the described resource using the specified attributes.



113
114
115
# File 'lib/vend/base.rb', line 113

def self.build(client, attrs)
  self.new(client, :attrs => attrs)
end

.build_from_json(client, json) ⇒ Object

Builds a collection of instances from a JSON response



118
119
120
121
122
# File 'lib/vend/base.rb', line 118

def self.build_from_json(client, json)
  json[collection_name].map do |attrs|
    self.build(client, attrs)
  end
end

.cast_attribute(attribute_name, type) ⇒ Object



23
24
25
# File 'lib/vend/base.rb', line 23

def self.cast_attribute(attribute_name, type)
  attribute_casts[attribute_name] = type
end

.collection_nameObject

Returns the endpoint name for a collection of this resource



37
38
39
# File 'lib/vend/base.rb', line 37

def self.collection_name
  endpoint_name.pluralize
end

.default_collection_request_argsObject

Override this with arguments that are required on every collection request. I.e, to default to 500 items per page:

def default_collection_request_args
  super.merge(:url_params => {:page_size => 500})
end


157
158
159
# File 'lib/vend/base.rb', line 157

def self.default_collection_request_args
  {}
end

.endpoint_nameObject

Returns the endpoint name for the resource, used in API urls when making requests.



32
33
34
# File 'lib/vend/base.rb', line 32

def self.endpoint_name
  self.name.split('::').last.underscore
end

.find(client, id) ⇒ Object

Attempts to pull a singular object from Vend through the singular GET endpoint.



138
139
140
141
# File 'lib/vend/base.rb', line 138

def self.find(client, id)
  response = client.request(singular_name(id))
  initialize_singular(client, response)
end

.findable_by(field, options = {}) ⇒ Object



94
95
96
97
98
99
100
101
# File 'lib/vend/base.rb', line 94

def self.findable_by(field, options = {})
  
  (class << self ; self ; end).instance_eval do
    define_method("find_by_#{field}") do |client, *args|
      search(client, options[:as] || field, *args)
    end
  end
end

.initialize_collection(client, endpoint, args = {}) ⇒ Object

Will initialize a collection of Resources from the APIs JSON Response.



131
132
133
# File 'lib/vend/base.rb', line 131

def self.initialize_collection(client, endpoint, args = {})
  ResourceCollection.new(client, self, endpoint, args)
end

.initialize_singular(client, json) ⇒ Object

Initializes a single object from a JSON response. Assumes the response is a JSON array with a single item.



126
127
128
# File 'lib/vend/base.rb', line 126

def self.initialize_singular(client, json)
  self.build(client, json[collection_name].first)
end

.paginates?Boolean

Whether or not this resource can be paginated, false by default. Override this method in specific classes to enable pagination for that resource.

Returns:

  • (Boolean)


146
147
148
# File 'lib/vend/base.rb', line 146

def self.paginates?
  false
end

.search(client, field, query) ⇒ Object

Sends a search request to the API and initializes a collection of Resources from the response. This method is only used internally by find_by_field methods.



105
106
107
108
109
# File 'lib/vend/base.rb', line 105

def self.search(client, field, query)
  initialize_collection(
    client, collection_name,  :url_params => { field.to_sym => query }
  )
end

.singular_name(id) ⇒ Object



45
46
47
# File 'lib/vend/base.rb', line 45

def self.singular_name(id)
  "#{collection_name}/#{id}"
end

.url_scope(method_name) ⇒ Object

Creates a class method that allows access to a filtered collection of resources on the API. For example:

class MyResource << Vend::Base
  url_scope :since
end

Will create a class method:

client.MyResource.since(argument)

That will call the following URL on the Vend API:

/api/my_resources/since/:argument

And return the corresponding collection of resources



85
86
87
88
89
90
91
92
# File 'lib/vend/base.rb', line 85

def self.url_scope(method_name)
  (class << self ; self ; end).instance_eval do
    define_method(method_name) do |client, arg|
      initialize_collection(client, collection_name).scope(method_name, arg)
    end
  end
  available_scopes << method_name
end

Instance Method Details

#deleteObject

Attempts to delete the resource. If an exception is thrown by delete!, it is caught and false is returned (typically when the resource is not a type which can be deleted).



184
185
186
187
188
# File 'lib/vend/base.rb', line 184

def delete
  delete!
rescue Vend::Resource::IllegalAction
  false
end

#delete!Object

Attempts to delete there resource. Will throw an exception when the attempt fails, otherwise will return true.



192
193
194
195
196
197
# File 'lib/vend/base.rb', line 192

def delete!
  raise(Vend::Resource::IllegalAction,
        "#{self.class.name} has no unique ID") unless attrs['id']
  client.request(singular_name, :method => :delete)
  true
end

#respond_to?(method_name) ⇒ Boolean

Overrides respond_to? to query the attrs hash for the key before proxying it to the object

Returns:

  • (Boolean)


163
164
165
166
167
168
169
# File 'lib/vend/base.rb', line 163

def respond_to?(method_name)
  if attrs.keys.include? method_name.to_s
    true
  else
    super(method_name)
  end
end

#singular_nameObject



41
42
43
# File 'lib/vend/base.rb', line 41

def singular_name
  self.class.singular_name(id)
end