Class: ZendeskAPI::Collection

Inherits:
Object
  • Object
show all
Includes:
Rescue
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 =
[:include, :ids, :only]

Instance Attribute Summary collapse

Instance Method Summary collapse

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.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/zendesk_api/collection.rb', line 23

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

  # 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.



251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/zendesk_api/collection.rb', line 251

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:



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

def association
  @association
end

Instance Method Details

#<<(item) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/zendesk_api/collection.rb', line 115

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.



241
242
243
244
245
246
# File 'lib/zendesk_api/collection.rb', line 241

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).



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

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



54
55
56
57
# File 'lib/zendesk_api/collection.rb', line 54

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



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

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



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/zendesk_api/collection.rb', line 182

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



135
136
137
138
139
140
141
142
143
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
# File 'lib/zendesk_api/collection.rb', line 135

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?}

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

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

  @count = (response.body["count"] || @resources.size).to_i
  @next_page, @prev_page = response.body["next_page"], response.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

  @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



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

def find(opts = {})
  opts.merge!(:association => @association)
  @resource_class.find(@client, @options.merge(opts))
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.



210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/zendesk_api/collection.rb', line 210

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



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

alias :orig_to_s :to_s

#page(number) ⇒ Collection

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

Returns:



93
94
95
96
97
# File 'lib/zendesk_api/collection.rb', line 93

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

#pathObject



129
130
131
# File 'lib/zendesk_api/collection.rb', line 129

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:



85
86
87
88
89
# File 'lib/zendesk_api/collection.rb', line 85

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.



227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/zendesk_api/collection.rb', line 227

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



201
202
203
204
# File 'lib/zendesk_api/collection.rb', line 201

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:



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/zendesk_api/collection.rb', line 101

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

      item
    end
  end

  self
end

#to_aObject

Alias for fetch(false)



176
177
178
# File 'lib/zendesk_api/collection.rb', line 176

def to_a
  fetch
end

#to_aryObject



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

def to_ary; nil; end

#to_sObject



266
267
268
269
270
271
272
# File 'lib/zendesk_api/collection.rb', line 266

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



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

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