zendesk_api 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.yardopts CHANGED
@@ -1 +1,8 @@
1
- --tag internal --hide-tag internal --no-private --protected lib/**/*.rb -e util/resource_handler.rb -e util/verb_handler.rb - Readme.md
1
+ --tag internal
2
+ --hide-tag internal
3
+ --no-private
4
+ --protected lib/**/*.rb
5
+ --load ./util/resource_handler.rb
6
+ --load ./util/verb_handler.rb
7
+ -
8
+ Readme.md
data/Gemfile.lock CHANGED
@@ -13,7 +13,7 @@ GIT
13
13
  PATH
14
14
  remote: .
15
15
  specs:
16
- zendesk_api (0.2.5)
16
+ zendesk_api (0.2.6)
17
17
  faraday (>= 0.8.0)
18
18
  faraday_middleware (>= 0.8.7)
19
19
  hashie
@@ -63,7 +63,7 @@ GEM
63
63
  inflection (1.0.0)
64
64
  jruby-openssl (0.8.2)
65
65
  bouncy-castle-java (>= 1.5.0146.1)
66
- json (1.7.6)
66
+ json (1.7.7)
67
67
  mime-types (1.20.1)
68
68
  mongoid (3.0.21)
69
69
  activemodel (~> 3.1)
@@ -58,34 +58,11 @@ module ZendeskAPI
58
58
 
59
59
  resources.each do |resource|
60
60
  if resource.key?(plural_key) # Grab associations from child_ids field on resource
61
- ids = resource.send(plural_key)
62
-
63
- resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
64
- ids.include?(side_load[options.include_key])
65
- }))
61
+ side_load_from_child_ids(resource, side_loads, plural_key)
66
62
  elsif resource.key?(key) || options.singular
67
- # Either grab association from child_id field on resource or parent_id on child resource
68
- if resource.key?(key)
69
- id = resource.send(key)
70
- include_key = options.include_key
71
- else
72
- id = resource.id
73
- include_key = "#{resource.class.singular_resource_name}_id"
74
- end
75
-
76
- next unless id
77
-
78
- side_load = side_loads.detect do |side_load|
79
- id == side_load[include_key]
80
- end
81
-
82
- resource.send("#{options.name}=", side_load) if side_load
63
+ side_load_from_child_or_parent_id(resource, side_loads, key)
83
64
  else # Grab associations from parent_id field from multiple child resources
84
- key = "#{resource.class.singular_resource_name}_id"
85
-
86
- resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
87
- side_load[key] == resource.id
88
- }))
65
+ side_load_from_parent_id(resource, side_loads, key)
89
66
  end
90
67
  end
91
68
  end
@@ -102,6 +79,41 @@ module ZendeskAPI
102
79
  end
103
80
  end
104
81
 
82
+ def side_load_from_parent_id(resource, side_loads, key)
83
+ key = "#{resource.class.singular_resource_name}_id"
84
+
85
+ resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
86
+ side_load[key] == resource.id
87
+ }))
88
+ end
89
+
90
+ def side_load_from_child_ids(resource, side_loads, plural_key)
91
+ ids = resource.send(plural_key)
92
+
93
+ resource.send("#{options.name}=", _side_load(resource, side_loads.select {|side_load|
94
+ ids.include?(side_load[options.include_key])
95
+ }))
96
+ end
97
+
98
+ def side_load_from_child_or_parent_id(resource, side_loads, key)
99
+ # Either grab association from child_id field on resource or parent_id on child resource
100
+ if resource.key?(key)
101
+ id = resource.send(key)
102
+ include_key = options.include_key
103
+ else
104
+ id = resource.id
105
+ include_key = "#{resource.class.singular_resource_name}_id"
106
+ end
107
+
108
+ return unless id
109
+
110
+ side_load = side_loads.detect do |side_load|
111
+ id == side_load[include_key]
112
+ end
113
+
114
+ resource.send("#{options.name}=", side_load) if side_load
115
+ end
116
+
105
117
  def build_parent_namespace(parent_class, instance, options, original_options)
106
118
  return unless association_on_parent = parent_class.associations.detect {|a| a[:class] == @options[:class] }
107
119
  [
@@ -134,179 +146,4 @@ module ZendeskAPI
134
146
  end
135
147
  end
136
148
  end
137
-
138
- # This module holds association method for resources.
139
- # Associations can be loaded in three ways:
140
- # * Commonly used resources are automatically side-loaded server side and sent along with their parent object.
141
- # * Associated resource ids are sent and are then loaded one-by-one into the parent collection.
142
- # * The association is represented with Rails' nested association urls (such as tickets/:id/groups) and are loaded that way.
143
- #
144
- # @private
145
- module Associations
146
- def self.included(base)
147
- base.send(:extend, ClassMethods)
148
- end
149
-
150
- def wrap_resource(resource, klass, class_level_association)
151
- instance_association = Association.new(class_level_association.merge(:parent => self))
152
- case resource
153
- when Hash
154
- klass.new(@client, resource.merge(:association => instance_association))
155
- when String, Fixnum
156
- klass.new(@client, :id => resource, :association => instance_association)
157
- else
158
- resource.association = instance_association
159
- resource
160
- end
161
- end
162
-
163
- # @private
164
- module ClassMethods
165
- include Rescue
166
-
167
- def associations
168
- @associations ||= []
169
- end
170
-
171
- def associated_with(name)
172
- associations.inject([]) do |associated_with, association|
173
- if association[:include] == name.to_s
174
- associated_with.push(Association.new(association))
175
- end
176
-
177
- associated_with
178
- end
179
- end
180
-
181
- # Represents a parent-to-child association between resources. Options to pass in are: class, path.
182
- # @param [Symbol] resource_name_or_class The underlying resource name or a class to get it from
183
- # @param [Hash] class_level_options The options to pass to the method definition.
184
- def has(resource_name_or_class, class_level_options = {})
185
- if klass = class_level_options.delete(:class)
186
- resource_name = resource_name_or_class
187
- else
188
- klass = resource_name_or_class
189
- resource_name = klass.singular_resource_name
190
- end
191
-
192
- class_level_association = {
193
- :class => klass,
194
- :name => resource_name,
195
- :inline => class_level_options.delete(:inline),
196
- :path => class_level_options.delete(:path),
197
- :include => (class_level_options.delete(:include) || klass.resource_name).to_s,
198
- :include_key => (class_level_options.delete(:include_key) || :id).to_s,
199
- :singular => true
200
- }
201
-
202
- associations << class_level_association
203
-
204
- id_column = "#{resource_name}_id"
205
-
206
- define_method "#{resource_name}_used?" do
207
- !!instance_variable_get("@#{resource_name}")
208
- end
209
-
210
- define_method resource_name do |*args|
211
- instance_options = args.last.is_a?(Hash) ? args.pop : {}
212
-
213
- # return if cached
214
- cached = instance_variable_get("@#{resource_name}")
215
- return cached if cached && !instance_options[:reload]
216
-
217
- # find and cache association
218
- instance_association = Association.new(class_level_association.merge(:parent => self))
219
- resource = if klass.respond_to?(:find) && resource_id = method_missing(id_column)
220
- klass.find(@client, :id => resource_id, :association => instance_association)
221
- elsif found = method_missing(resource_name.to_sym)
222
- wrap_resource(found, klass, class_level_association)
223
- elsif klass.superclass == DataResource
224
- rescue_client_error do
225
- response = @client.connection.get(instance_association.generate_path(:with_parent => true))
226
- klass.new(@client, response.body[klass.singular_resource_name].merge(:association => instance_association))
227
- end
228
- end
229
-
230
- send("#{id_column}=", resource.id) if resource && has_key?(id_column)
231
- instance_variable_set("@#{resource_name}", resource)
232
- end
233
-
234
- define_method "#{resource_name}=" do |resource|
235
- resource = wrap_resource(resource, klass, class_level_association)
236
- send("#{id_column}=", resource.id) if has_key?(id_column)
237
- instance_variable_set("@#{resource_name}", resource)
238
- end
239
- end
240
-
241
- # Represents a parent-to-children association between resources. Options to pass in are: class, path.
242
- # @param [Symbol] resource_name_or_class The underlying resource name or class to get it from
243
- # @param [Hash] class_level_options The options to pass to the method definition.
244
- def has_many(resource_name_or_class, class_level_options = {})
245
- if klass = class_level_options.delete(:class)
246
- resource_name = resource_name_or_class
247
- else
248
- klass = resource_name_or_class
249
- resource_name = klass.resource_name
250
- end
251
-
252
- class_level_association = {
253
- :class => klass,
254
- :name => resource_name,
255
- :inline => class_level_options.delete(:inline),
256
- :path => class_level_options.delete(:path),
257
- :include => (class_level_options.delete(:include) || klass.resource_name).to_s,
258
- :include_key => (class_level_options.delete(:include_key) || :id).to_s,
259
- :singular => false
260
- }
261
-
262
- associations << class_level_association
263
-
264
- id_column = "#{resource_name}_ids"
265
-
266
- define_method "#{resource_name}_used?" do
267
- !!instance_variable_get("@#{resource_name}")
268
- end
269
-
270
- define_method resource_name do |*args|
271
- instance_opts = args.last.is_a?(Hash) ? args.pop : {}
272
-
273
- # return if cached
274
- cached = instance_variable_get("@#{resource_name}")
275
- return cached if cached && !instance_opts[:reload]
276
-
277
- # find and cache association
278
- instance_association = Association.new(class_level_association.merge(:parent => self))
279
- singular_resource_name = Inflection.singular(resource_name.to_s)
280
-
281
- resources = if (ids = method_missing("#{singular_resource_name}_ids")) && ids.any?
282
- ids.map do |id|
283
- klass.find(@client, :id => id, :association => instance_association)
284
- end.compact
285
- elsif (resources = method_missing(resource_name.to_sym)) && resources.any?
286
- resources.map do |res|
287
- klass.new(@client, res.merge(:association => instance_association))
288
- end
289
- else
290
- ZendeskAPI::Collection.new(@client, klass, instance_opts.merge(:association => instance_association))
291
- end
292
-
293
- send("#{id_column}=", resources.map(&:id)) if resource && has_key?(id_column)
294
- instance_variable_set("@#{resource_name}", resources)
295
- end
296
-
297
- define_method "#{resource_name}=" do |resources|
298
- if resources.is_a?(Array)
299
- resources.map! { |attr| wrap_resource(attr, klass, class_level_association) }
300
- send(resource_name).replace(resources)
301
- else
302
- resources.association = instance_association
303
- instance_variable_set("@#{resource_name}", resources)
304
- end
305
-
306
- send("#{id_column}=", resources.map(&:id)) if resources && has_key?(id_column)
307
- resource
308
- end
309
- end
310
- end
311
- end
312
149
  end
@@ -0,0 +1,178 @@
1
+ require 'zendesk_api/helpers'
2
+
3
+ module ZendeskAPI
4
+ # This module holds association method for resources.
5
+ # Associations can be loaded in three ways:
6
+ # * Commonly used resources are automatically side-loaded server side and sent along with their parent object.
7
+ # * Associated resource ids are sent and are then loaded one-by-one into the parent collection.
8
+ # * The association is represented with Rails' nested association urls (such as tickets/:id/groups) and are loaded that way.
9
+ #
10
+ # @private
11
+ module Associations
12
+ def self.included(base)
13
+ base.send(:extend, ClassMethods)
14
+ end
15
+
16
+ def wrap_resource(resource, klass, class_level_association)
17
+ instance_association = Association.new(class_level_association.merge(:parent => self))
18
+ case resource
19
+ when Hash
20
+ klass.new(@client, resource.merge(:association => instance_association))
21
+ when String, Fixnum
22
+ klass.new(@client, :id => resource, :association => instance_association)
23
+ else
24
+ resource.association = instance_association
25
+ resource
26
+ end
27
+ end
28
+
29
+ # @private
30
+ module ClassMethods
31
+ include Rescue
32
+
33
+ def associations
34
+ @associations ||= []
35
+ end
36
+
37
+ def associated_with(name)
38
+ associations.inject([]) do |associated_with, association|
39
+ if association[:include] == name.to_s
40
+ associated_with.push(Association.new(association))
41
+ end
42
+
43
+ associated_with
44
+ end
45
+ end
46
+
47
+ # Represents a parent-to-child association between resources. Options to pass in are: class, path.
48
+ # @param [Symbol] resource_name_or_class The underlying resource name or a class to get it from
49
+ # @param [Hash] class_level_options The options to pass to the method definition.
50
+ def has(resource_name_or_class, class_level_options = {})
51
+ if klass = class_level_options.delete(:class)
52
+ resource_name = resource_name_or_class
53
+ else
54
+ klass = resource_name_or_class
55
+ resource_name = klass.singular_resource_name
56
+ end
57
+
58
+ class_level_association = {
59
+ :class => klass,
60
+ :name => resource_name,
61
+ :inline => class_level_options.delete(:inline),
62
+ :path => class_level_options.delete(:path),
63
+ :include => (class_level_options.delete(:include) || klass.resource_name).to_s,
64
+ :include_key => (class_level_options.delete(:include_key) || :id).to_s,
65
+ :singular => true
66
+ }
67
+
68
+ associations << class_level_association
69
+
70
+ id_column = "#{resource_name}_id"
71
+
72
+ define_method "#{resource_name}_used?" do
73
+ !!instance_variable_get("@#{resource_name}")
74
+ end
75
+
76
+ define_method resource_name do |*args|
77
+ instance_options = args.last.is_a?(Hash) ? args.pop : {}
78
+
79
+ # return if cached
80
+ cached = instance_variable_get("@#{resource_name}")
81
+ return cached if cached && !instance_options[:reload]
82
+
83
+ # find and cache association
84
+ instance_association = Association.new(class_level_association.merge(:parent => self))
85
+ resource = if klass.respond_to?(:find) && resource_id = method_missing(id_column)
86
+ klass.find(@client, :id => resource_id, :association => instance_association)
87
+ elsif found = method_missing(resource_name.to_sym)
88
+ wrap_resource(found, klass, class_level_association)
89
+ elsif klass.superclass == DataResource
90
+ rescue_client_error do
91
+ response = @client.connection.get(instance_association.generate_path(:with_parent => true))
92
+ klass.new(@client, response.body[klass.singular_resource_name].merge(:association => instance_association))
93
+ end
94
+ end
95
+
96
+ send("#{id_column}=", resource.id) if resource && has_key?(id_column)
97
+ instance_variable_set("@#{resource_name}", resource)
98
+ end
99
+
100
+ define_method "#{resource_name}=" do |resource|
101
+ resource = wrap_resource(resource, klass, class_level_association)
102
+ send("#{id_column}=", resource.id) if has_key?(id_column)
103
+ instance_variable_set("@#{resource_name}", resource)
104
+ end
105
+ end
106
+
107
+ # Represents a parent-to-children association between resources. Options to pass in are: class, path.
108
+ # @param [Symbol] resource_name_or_class The underlying resource name or class to get it from
109
+ # @param [Hash] class_level_options The options to pass to the method definition.
110
+ def has_many(resource_name_or_class, class_level_options = {})
111
+ if klass = class_level_options.delete(:class)
112
+ resource_name = resource_name_or_class
113
+ else
114
+ klass = resource_name_or_class
115
+ resource_name = klass.resource_name
116
+ end
117
+
118
+ class_level_association = {
119
+ :class => klass,
120
+ :name => resource_name,
121
+ :inline => class_level_options.delete(:inline),
122
+ :path => class_level_options.delete(:path),
123
+ :include => (class_level_options.delete(:include) || klass.resource_name).to_s,
124
+ :include_key => (class_level_options.delete(:include_key) || :id).to_s,
125
+ :singular => false
126
+ }
127
+
128
+ associations << class_level_association
129
+
130
+ id_column = "#{resource_name}_ids"
131
+
132
+ define_method "#{resource_name}_used?" do
133
+ !!instance_variable_get("@#{resource_name}")
134
+ end
135
+
136
+ define_method resource_name do |*args|
137
+ instance_opts = args.last.is_a?(Hash) ? args.pop : {}
138
+
139
+ # return if cached
140
+ cached = instance_variable_get("@#{resource_name}")
141
+ return cached if cached && !instance_opts[:reload]
142
+
143
+ # find and cache association
144
+ instance_association = Association.new(class_level_association.merge(:parent => self))
145
+ singular_resource_name = Inflection.singular(resource_name.to_s)
146
+
147
+ resources = if (ids = method_missing("#{singular_resource_name}_ids")) && ids.any?
148
+ ids.map do |id|
149
+ klass.find(@client, :id => id, :association => instance_association)
150
+ end.compact
151
+ elsif (resources = method_missing(resource_name.to_sym)) && resources.any?
152
+ resources.map do |res|
153
+ klass.new(@client, res.merge(:association => instance_association))
154
+ end
155
+ else
156
+ ZendeskAPI::Collection.new(@client, klass, instance_opts.merge(:association => instance_association))
157
+ end
158
+
159
+ send("#{id_column}=", resources.map(&:id)) if resource && has_key?(id_column)
160
+ instance_variable_set("@#{resource_name}", resources)
161
+ end
162
+
163
+ define_method "#{resource_name}=" do |resources|
164
+ if resources.is_a?(Array)
165
+ resources.map! { |attr| wrap_resource(attr, klass, class_level_association) }
166
+ send(resource_name).replace(resources)
167
+ else
168
+ resources.association = instance_association
169
+ instance_variable_set("@#{resource_name}", resources)
170
+ end
171
+
172
+ send("#{id_column}=", resources.map(&:id)) if resources && has_key?(id_column)
173
+ resource
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -14,22 +14,25 @@ module ZendeskAPI
14
14
  @cache_key_prefix = options.fetch(:cache_key_prefix, :faraday_etags)
15
15
  end
16
16
 
17
+ def cache_key(env)
18
+ [@cache_key_prefix, env[:url].to_s]
19
+ end
20
+
17
21
  def call(env)
18
22
  return @app.call(env) unless [:get, :head].include?(env[:method])
19
- cache_key = [@cache_key_prefix, env[:url].to_s]
20
23
 
21
24
  # send known etag
22
- if cached = @cache.read(cache_key)
25
+ cached = @cache.read(cache_key(env))
26
+
27
+ if cached
23
28
  env[:request_headers]["If-None-Match"] ||= cached[:response_headers]["Etag"]
24
29
  end
25
30
 
26
31
  @app.call(env).on_complete do
27
32
  if cached && env[:status] == 304 # not modified
28
33
  env[:body] = cached[:body]
29
- end
30
-
31
- if env[:status] == 200 && env[:response_headers]["Etag"] # modified and cacheable
32
- @cache.write(cache_key, env)
34
+ elsif env[:status] == 200 && env[:response_headers]["Etag"] # modified and cacheable
35
+ @cache.write(cache_key(env), env)
33
36
  end
34
37
  end
35
38
  end
@@ -2,6 +2,7 @@ require 'zendesk_api/helpers'
2
2
  require 'zendesk_api/trackie'
3
3
  require 'zendesk_api/actions'
4
4
  require 'zendesk_api/association'
5
+ require 'zendesk_api/associations'
5
6
  require 'zendesk_api/verbs'
6
7
 
7
8
  module ZendeskAPI
@@ -29,17 +29,7 @@ module ZendeskAPI::Server
29
29
  end
30
30
 
31
31
  begin
32
- response = client.connection.send(@method, @path) do |request|
33
- request.params = @url_params.inject({}) do |accum, h|
34
- accum.merge(h["name"] => h["value"])
35
- end
36
-
37
- if @method != :get && @json && !@json.empty?
38
- request.body = JSON.parse(@json)
39
- end
40
-
41
- set_request(request.to_env(client.connection))
42
- end
32
+ response = get_response
43
33
  rescue Faraday::Error::ConnectionFailed => e
44
34
  @error = "The connection failed"
45
35
  rescue Faraday::Error::ClientError => e
@@ -55,6 +45,20 @@ module ZendeskAPI::Server
55
45
  end
56
46
  end
57
47
 
48
+ def get_response
49
+ client.connection.send(@method, @path) do |request|
50
+ request.params = @url_params.inject({}) do |accum, h|
51
+ accum.merge(h["name"] => h["value"])
52
+ end
53
+
54
+ if @method != :get && @json && !@json.empty?
55
+ request.body = JSON.parse(@json)
56
+ end
57
+
58
+ set_request(request.to_env(client.connection))
59
+ end
60
+ end
61
+
58
62
  def map_headers(headers)
59
63
  headers.map do |k,v|
60
64
  name = k.split("-").map(&:capitalize).join("-")
@@ -1,3 +1,3 @@
1
1
  module ZendeskAPI
2
- VERSION = "0.2.5"
2
+ VERSION = "0.2.6"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zendesk_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-06 00:00:00.000000000 Z
13
+ date: 2013-02-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bump
@@ -244,6 +244,7 @@ files:
244
244
  - lib/zendesk_api.rb
245
245
  - lib/zendesk_api/actions.rb
246
246
  - lib/zendesk_api/association.rb
247
+ - lib/zendesk_api/associations.rb
247
248
  - lib/zendesk_api/client.rb
248
249
  - lib/zendesk_api/collection.rb
249
250
  - lib/zendesk_api/configuration.rb