Class: ZendeskAPI::Collection

Inherits:
Object
  • Object
show all
Includes:
Rescue, Sideloading
Defined in:
lib/zendesk_api/collection.rb

Overview

Represents a collection of resources. Lazily loaded, resources aren’t actually fetched until explicitly needed (e.g. #each, #fetch).

Constant Summary collapse

SPECIALLY_JOINED_PARAMS =
[:ids, :only]

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Sideloading

#set_includes

Constructor Details

#initialize(client, resource, options = {}) ⇒ Collection

Creates a new Collection instance. Does not fetch resources. Additional options are: verb (default: GET), path (default: resource param), page, per_page.

Parameters:

  • client (Client)

    The ZendeskAPI::Client to use.

  • resource (String)

    The resource being collected.

  • options (Hash) (defaults to: {})

    Any additional options to be passed in.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/zendesk_api/collection.rb', line 27

def initialize(client, resource, options = {})
  @client, @resource = client, resource.resource_name
  @options = Hashie::Mash.new(options)

  @verb = @options.delete(:verb)
  @collection_path = @options.delete(:collection_path)

  association_options = { :path => @options.delete(:path) }
  association_options[:path] ||= @collection_path.join("/") if @collection_path
  @association = @options.delete(:association) || Association.new(association_options.merge(:class => resource))

  # some params use comma-joined strings instead of query-based arrays for multiple values
  @options.each do |k, v|
    if SPECIALLY_JOINED_PARAMS.include?(k.to_sym) && v.is_a?(Array)
      @options[k] = v.join(',')
    end
  end

  @collection_path ||= [@resource]
  @resource_class = resource
  @fetchable = true
  @includes = Array(@options.delete(:include))

  # Used for Attachments, TicketComment
  if @resource_class.superclass == ZendeskAPI::Data
    @resources = []
    @fetchable = false
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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

Sends methods to underlying array of resources.



271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/zendesk_api/collection.rb', line 271

def method_missing(name, *args, &block)
  methods = @resource_class.singleton_methods(false).map(&:to_sym)

  if methods.include?(name)
    @resource_class.send(name, @client, *args, &block)
  elsif Array.new.respond_to?(name)
    to_a.send(name, *args, &block)
  else
    opts = args.last.is_a?(Hash) ? args.last : {}
    opts.merge!(:collection_path => @collection_path.dup.push(name))
    self.class.new(@client, @resource_class, @options.merge(opts))
  end
end

Instance Attribute Details

#associationZendeskAPI::Association (readonly)

Returns The class association.

Returns:



17
18
19
# File 'lib/zendesk_api/collection.rb', line 17

def association
  @association
end

#responseFaraday::Response (readonly)

Returns The last response.

Returns:

  • (Faraday::Response)

    The last response



20
21
22
# File 'lib/zendesk_api/collection.rb', line 20

def response
  @response
end

Instance Method Details

#<<(item) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/zendesk_api/collection.rb', line 124

def <<(item)
  fetch
  if item.is_a?(Resource)
    if item.is_a?(@resource_class)
      @resources << item
    else
      raise "this collection is for #{@resource_class}"
    end
  else
    item.merge!(:association => @association) if item.is_a?(Hash)
    @resources << @resource_class.new(@client, item)
  end
end

#clear_cacheObject

Clears all cached resources and associated values.



261
262
263
264
265
266
# File 'lib/zendesk_api/collection.rb', line 261

def clear_cache
  @resources = nil
  @count = nil
  @next_page = nil
  @prev_page = nil
end

#countNumber

Returns The total number of resources server-side (disregarding pagination).

Returns:

  • (Number)

    The total number of resources server-side (disregarding pagination).



83
84
85
86
# File 'lib/zendesk_api/collection.rb', line 83

def count
  fetch
  @count
end

#create(attributes = {}) ⇒ Object

Passes arguments and the proper path to the resource class method.

Parameters:

  • attributes (Hash) (defaults to: {})

    Attributes to pass to Create#create



59
60
61
62
# File 'lib/zendesk_api/collection.rb', line 59

def create(attributes = {})
  attributes.merge!(:association => @association)
  @resource_class.create(@client, @options.merge(attributes))
end

#destroy(opts = {}) ⇒ Object

Passes arguments and the proper path to the resource class method.

Parameters:

  • attributes (Hash)

    Attributes to pass to Create#create



77
78
79
80
# File 'lib/zendesk_api/collection.rb', line 77

def destroy(opts = {})
  opts.merge!(:association => association)
  @resource_class.destroy(@client, @options.merge(opts))
end

#each_page(&block) ⇒ Object

Calls #each on every page with the passed in block

Parameters:

  • block (Block)

    Passed to #each



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/zendesk_api/collection.rb', line 202

def each_page(&block)
  page(nil)
  clear_cache

  while !empty?
    each do |resource|
      arguments = [resource, @options["page"] || 1]

      if block.arity >= 0
        arguments = arguments.take(block.arity)
      end

      block.call(*arguments)
    end

    self.next
  end
end

#fetch(reload = false) ⇒ Object

Executes actual GET from API and loads resources into proper class.

Parameters:

  • reload (Boolean) (defaults to: false)

    Whether to disregard cache



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/zendesk_api/collection.rb', line 144

def fetch(reload = false)
  return @resources if @resources && (!@fetchable || !reload)

  if association && association.options.parent && association.options.parent.new_record?
    return @resources = []
  end

  if @query
    path = @query
    @query = nil
  else
    path = self.path
  end

  @response = @client.connection.send(@verb || "get", path) do |req|
    opts = @options.delete_if {|k, v| v.nil?}

    req.params.merge!(:include => @includes.join(",")) if @includes.any?

    if %w{put post}.include?(@verb.to_s)
      req.body = opts
    else
      req.params.merge!(opts)
    end
  end

  body = @response.body.dup

  results = body.delete(@resource_class.model_key) || body.delete("results")
  @resources = results.map {|res| @resource_class.new(@client, res)}

  set_page_and_count(body)
  set_includes(@resources, @includes, body)

  @resources
end

#find(opts = {}) ⇒ Object

Passes arguments and the proper path to the resource class method.

Parameters:

  • attributes (Hash)

    Attributes to pass to Create#create



65
66
67
68
# File 'lib/zendesk_api/collection.rb', line 65

def find(opts = {})
  opts.merge!(:association => @association)
  @resource_class.find(@client, @options.merge(opts))
end

#include(*sideloads) ⇒ Object



120
121
122
# File 'lib/zendesk_api/collection.rb', line 120

def include(*sideloads)
  self.tap { @includes.concat(sideloads.map(&:to_s)) }
end

#nextObject

Find the next page. Does one of three things:

  • If there is already a page number in the options hash, it increases it and invalidates the cache, returning the new page number.

  • If there is a next_page url cached, it executes a fetch on that url and returns the results.

  • Otherwise, returns an empty array.



230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/zendesk_api/collection.rb', line 230

def next
  if @options["page"]
    clear_cache
    @options["page"] += 1
  elsif @next_page
    @query = @next_page
    fetch(true)
  else
    clear_cache
    @resources = []
  end
end

#orig_to_sObject



285
# File 'lib/zendesk_api/collection.rb', line 285

alias :orig_to_s :to_s

#page(number) ⇒ Collection

Changes the page option. Returns self, so it can be chained. No execution.

Returns:



98
99
100
101
102
# File 'lib/zendesk_api/collection.rb', line 98

def page(number)
  clear_cache if number
  @options["page"] = number
  self
end

#pathObject



138
139
140
# File 'lib/zendesk_api/collection.rb', line 138

def path
  @association.generate_path(:with_parent => true)
end

#per_page(count) ⇒ Collection

Changes the per_page option. Returns self, so it can be chained. No execution.

Returns:



90
91
92
93
94
# File 'lib/zendesk_api/collection.rb', line 90

def per_page(count)
  clear_cache if count
  @options["per_page"] = count
  self
end

#prevObject

Find the previous page. Does one of three things:

  • If there is already a page number in the options hash, it increases it and invalidates the cache, returning the new page number.

  • If there is a prev_page url cached, it executes a fetch on that url and returns the results.

  • Otherwise, returns an empty array.



247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/zendesk_api/collection.rb', line 247

def prev
  if @options["page"] && @options["page"] > 1
    clear_cache
    @options["page"] -= 1
  elsif @prev_page
    @query = @prev_page
    fetch(true)
  else
    clear_cache
    @resources = []
  end
end

#replace(collection) ⇒ Object



221
222
223
224
# File 'lib/zendesk_api/collection.rb', line 221

def replace(collection)
  raise "this collection is for #{@resource_class}" if collection.any?{|r| !r.is_a?(@resource_class) }
  @resources = collection
end

#saveCollection

Saves all newly created resources stored in this collection.

Returns:



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/zendesk_api/collection.rb', line 106

def save
  if @resources
    @resources.map! do |item|
      unless !item.respond_to?(:save) || item.changes.empty?
        item.save
      end

      item
    end
  end

  self
end

#set_page_and_count(body) ⇒ Object



181
182
183
184
185
186
187
188
189
190
# File 'lib/zendesk_api/collection.rb', line 181

def set_page_and_count(body)
  @count = (body["count"] || @resources.size).to_i
  @next_page, @prev_page = body["next_page"], body["previous_page"]

  if @next_page =~ /page=(\d+)/
    @options["page"] = $1.to_i - 1
  elsif @prev_page =~ /page=(\d+)/
    @options["page"] = $1.to_i + 1
  end
end

#to_aObject

Alias for fetch(false)



196
197
198
# File 'lib/zendesk_api/collection.rb', line 196

def to_a
  fetch
end

#to_aryObject



268
# File 'lib/zendesk_api/collection.rb', line 268

def to_ary; nil; end

#to_sObject



286
287
288
289
290
291
292
# File 'lib/zendesk_api/collection.rb', line 286

def to_s
  if @resources
    @resources.inspect
  else
    orig_to_s
  end
end

#update(opts = {}) ⇒ Object

Passes arguments and the proper path to the resource class method.

Parameters:

  • attributes (Hash)

    Attributes to pass to Create#create



71
72
73
74
# File 'lib/zendesk_api/collection.rb', line 71

def update(opts = {})
  opts.merge!(:association => @association)
  @resource_class.update(@client, @options.merge(opts))
end