desk_api 0.5.8 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/README.md +274 -120
  4. data/lib/desk_api.rb +2 -2
  5. data/lib/desk_api/client.rb +6 -1
  6. data/lib/desk_api/configuration.rb +34 -26
  7. data/lib/desk_api/request/encode_json.rb +11 -0
  8. data/lib/desk_api/request/oauth.rb +20 -0
  9. data/lib/desk_api/request/retry.rb +37 -42
  10. data/lib/desk_api/resource.rb +86 -22
  11. data/lib/desk_api/response/parse_dates.rb +28 -0
  12. data/lib/desk_api/response/parse_json.rb +9 -0
  13. data/lib/desk_api/response/raise_error.rb +11 -16
  14. data/lib/desk_api/version.rb +1 -1
  15. data/spec/cassettes/DeskApi_Resource/_all/iterates_over_each_resource_on_each_page.yml +1953 -0
  16. data/spec/cassettes/DeskApi_Resource/_each_page/iterates_over_each_page.yml +1953 -0
  17. data/spec/cassettes/DeskApi_Resource/_each_page/raises_NoMethodError_is_called_on_non-page_resources.yml +207 -0
  18. data/spec/cassettes/DeskApi_Resource/_each_page/uses_a_default_per_page_of_1000.yml +1953 -0
  19. data/spec/cassettes/DeskApi_Resource/_load/loads_the_resource_if_not_already_loaded.yml +205 -0
  20. data/spec/cassettes/DeskApi_Resource/_loaded_/returns_true_if_the_resource_is_loaded.yml +205 -0
  21. data/spec/cassettes/DeskApi_Resource/_next_/changes__definition_to_next_page.yml +407 -0
  22. data/spec/cassettes/DeskApi_Resource/_next_/returns_nil_on_the_last_page.yml +315 -0
  23. data/spec/cassettes/DeskApi_Resource/_request/sends_request_through_a_client_and_returns_Faraday_Response.yml +207 -0
  24. data/spec/cassettes/DeskApi_Resource/_reset_/sets__links__embedded__changed_and__loaded_to_default_values.yml +253 -0
  25. data/spec/cassettes/DeskApi_Resource/_to_hash/converts_embedded_resources_to_hashes.yml +251 -0
  26. data/spec/cassettes/DeskApi_Resource/_to_hash/returns_a_hash_for_a_desk_resource.yml +66 -0
  27. data/spec/cassettes/DeskApi_Resource/_update/can_handle_action_params.yml +427 -0
  28. data/spec/desk_api/client_spec.rb +23 -17
  29. data/spec/desk_api/configuration_spec.rb +49 -41
  30. data/spec/desk_api/default_spec.rb +3 -3
  31. data/spec/desk_api/error_spec.rb +9 -7
  32. data/spec/desk_api/rate_limit_spec.rb +1 -1
  33. data/spec/desk_api/request/encode_json_spec.rb +33 -0
  34. data/spec/desk_api/request/oauth_spec.rb +31 -0
  35. data/spec/desk_api/request/retry_spec.rb +4 -4
  36. data/spec/desk_api/resource_spec.rb +247 -71
  37. data/spec/desk_api/response/parse_dates_spec.rb +34 -0
  38. data/spec/desk_api/response/parse_json_spec.rb +34 -0
  39. data/spec/desk_api/response/raise_error_spec.rb +31 -0
  40. data/spec/desk_api_spec.rb +6 -6
  41. data/spec/spec_helper.rb +2 -2
  42. data/spec/stubs/article.json +51 -0
  43. data/spec/stubs/to_hash_embed.json +1 -0
  44. metadata +78 -28
  45. data/.coveralls.yml +0 -1
  46. data/.gitignore +0 -23
  47. data/.rspec +0 -1
  48. data/.travis.yml +0 -4
  49. data/.yardopts +0 -3
  50. data/Gemfile +0 -10
  51. data/Guardfile +0 -5
  52. data/Rakefile +0 -32
  53. data/desk_api.gemspec +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 377a97983e2ace11f11987c8613ff3fedadcac9d
4
- data.tar.gz: 1abd58b7426e200881ed64f4442bac2d3e3596c3
3
+ metadata.gz: 6883196206272d0b4c6d3bb2f05162fc54b69f2f
4
+ data.tar.gz: ee8ed10269afb814092436c08fe175a630c6e152
5
5
  SHA512:
6
- metadata.gz: b5b702677936f9850abd90eadee90b2610ce7e4115425eb0d9f48a40f40724a0b3d842b98de3a2438160d9421ab7328d720b7ca22d12fbb328ec2a9910285239
7
- data.tar.gz: 013ca94e41377209aab11cb2c5e8a08149a42e140794d9530a25cb0806a5d68a5cf393fd8e48c6f5f83326ee5d597886bb7b0e691a338cac59b0fb8a8ccc0f76
6
+ metadata.gz: 0be30c22b23542152d31eb01cd93eaae53eee661c775792922db110069084e1ef579a669edb72c98e95f44eaf1768f4ada722f2ee153a2131057bbe2d544b830
7
+ data.tar.gz: d8570d5cffca4ab9b65b77d5ac6ab06f1e6f0490cde0fa28f868f2a6fe71a723f7718b1386cb88460e2b8098895872c45fbcc97694f45a5aebdf926684ee81ee
data/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
- Copyright (c) 2013 Thomas Stachl <tom@desk.com>
1
+ Copyright (c) 2013-2014 Thomas Stachl <tstachl@salesforce.com>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
5
5
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
6
 
7
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,56 +1,183 @@
1
- # desk.com APIv2 [![Build Status](https://secure.travis-ci.org/tstachl/desk.png)](http://travis-ci.org/tstachl/desk) [![Coverage Status](https://coveralls.io/repos/tstachl/desk/badge.png?branch=develop)](https://coveralls.io/r/tstachl/desk?branch=develop) [![Dependency Status](https://gemnasium.com/tstachl/desk.png)](https://gemnasium.com/tstachl/desk)
1
+ # DeskApi a client for APIv2
2
2
 
3
- desk.com has released v2 of their REST API a few months ago and provides a lot more functionality. You should read up on the current progress of the [API](http://dev.desk.com/API/changelog). This library wraps all of it into an easy to use ruby module. We'll try to keep up with the changes of the API but things might still break unexpectedly.
3
+ [![Build Status](https://secure.travis-ci.org/tstachl/desk_api.png)](http://travis-ci.org/tstachl/desk_api)
4
+ [![Coverage Status](https://coveralls.io/repos/tstachl/desk_api/badge.png?branch=develop)](https://coveralls.io/r/tstachl/desk_api?branch=develop)
5
+ [![Dependency Status](https://gemnasium.com/tstachl/desk_api.png)](https://gemnasium.com/tstachl/desk_api)
4
6
 
5
- ## Installation
7
+ ___
8
+ ## An Awesomely Unofficial Desk API Client
9
+ ___
10
+
11
+ DeskApi takes the capabilities of the Desk.com API and wraps them up in a Ruby
12
+ client so that it's easy-as-pie to get working with your support site's API.
13
+
14
+ Desk publishes a changelog monthly, which you can keep up with at
15
+ [dev.desk.com/API/changelog](http://dev.desk.com/API/changelog).
16
+
17
+ We do our best to keep DeskApi, but please
18
+ don't hesitate to open an [issue](https://github.com/tstachl/desk/issues) or send a [pull request](https://github.com/tstachl/desk/pulls) if you find a bug or would like to new functionality added.
19
+
20
+
21
+ ___
22
+ ## Getting Started
23
+ ___
24
+
25
+ ### Installation
26
+ Easy!
6
27
 
7
28
  ```ruby
8
29
  gem install desk_api
9
30
  ```
31
+ ___
32
+ ### Configuration
10
33
 
11
- ## Example
12
- This example shows you how to create a new client and establish a connection to the API. It shows the four request methods supported by the desk.com API (`GET`, `POST`, `PATCH` and `DELETE`).
34
+ There are two different ways to configure DeskApi to send and receive requests:
35
+
36
+ #### First Configuration Option
37
+
38
+ Configure `DeskApi` itself to send/receive requests by calling the `configure`
39
+ method to set up your authentication credentials:
13
40
 
14
41
  ```ruby
15
- # Basic Auth
16
- client = DeskApi::Client.new username: 'thomas@example.com', password: 'somepassword', subdomain: 'devel'
17
- # OAuth
42
+ DeskApi.configure do |config|
43
+ # basic authentication
44
+ config.username = 'thomas@example.com'
45
+ config.password = 'somepassword'
46
+
47
+ # oauth configuration
48
+ config.token = 'TOKEN'
49
+ config.token_secret = 'TOKEN_SECRET'
50
+ config.consumer_key = 'CONSUMER_KEY'
51
+ config.consumer_secret = 'CONSUMER_SECRET'
52
+
53
+ config.endpoint = 'https://devel.desk.com'
54
+ end
55
+
56
+ DeskApi.get '/api/v2/topics'
57
+ DeskApi.post '/api/v2/topics', name: 'My new Topic', allow_questions: true
58
+ DeskApi.patch '/api/v2/topics/1', name: 'Changed the Topic Name'
59
+ DeskApi.delete '/api/v2/topics/1'
60
+ ```
61
+
62
+ #### Second Configuration Option
63
+
64
+ Initialize a new `DeskApi::Client` to send/receive requests
65
+
66
+ This example shows you how to initialize a new client and the four main request
67
+ methods supported by the Desk.com API (`GET`, `POST`, `PATCH` and `DELETE`).
68
+
69
+ ```ruby
70
+ # basic authentication
71
+ client = DeskApi::Client.new username: 'thomas@example.com', password: 'somepassword', endpoint: 'https://devel.desk.com'
72
+ # oauth configuration
18
73
  client = DeskApi::Client.new({
19
74
  token: 'TOKEN',
20
75
  token_secret: 'TOKEN_SECRET',
21
76
  consumer_key: 'CONSUMER_KEY',
22
77
  consumer_secret: 'CONSUMER_SECRET',
23
- subdomain: 'devel'
78
+ endpoint: 'https://devel.desk.com'
24
79
  })
25
80
 
26
81
  response = client.get '/api/v2/topics'
27
82
  response = client.post '/api/v2/topics', name: 'My new Topic', allow_questions: true
28
83
  response = client.patch '/api/v2/topics/1', name: 'Changed the Topic Name'
29
- response = client.delete '/api/v2/topics/1'
84
+ response = client.delete '/api/v2/topics/1'
30
85
  ```
31
86
 
32
- For ease of use and if you only create one connection to the desk.com API you can use `DeskApi` directly:
87
+
88
+ ___
89
+ ## Resources
90
+ ___
91
+
92
+ Resources are automatically discovered by the DeskApi. When requesting a
93
+ resource from DeskAPI, the client sends the request and returns a
94
+ `DeskApi::Resource`. If the client receives an error back from the API a
95
+ `DeskApi::Error` is raised.
96
+
97
+ ___
98
+ ### Create Read Update Delete
99
+
100
+ One of the most important features; we support creating, updating and deleting
101
+ resources but not all resources can be deleted or updated or created, if that's
102
+ the case for the resource you're trying to update, it'll throw a
103
+ `DeskApi::Error::MethodNotAllowed` error. For ease of use and because we wanted
104
+ to build as less business logic into the wrapper as possible, all of the methods
105
+ are defined on each `DeskApi::Resource` and will be sent to desk.com. However
106
+ the API might respond with an error if you do things that aren't supported.
33
107
 
34
108
  ```ruby
35
- DeskApi.configure do |config|
36
- config.username = 'thomas@example.com'
37
- config.password = 'somepassword'
38
- config.subdomain = 'devel'
109
+ # let's create an article
110
+ new_article = DeskApi.articles.create({
111
+ subject: 'Some Subject',
112
+ body: 'Some Body',
113
+ _links: {
114
+ topic: DeskApi.topics.first.get_self
115
+ }
116
+ })
117
+
118
+ # as you can see here a `Resource' always includes a method `.get_self'
119
+ # which will return the link object to build relationships
120
+
121
+ # updating the article
122
+ updated_article = new_article.update subject: 'Updated Subject'
123
+
124
+ # deleting the article
125
+ if updated_article.delete == true
126
+ # article has been deleted
39
127
  end
40
128
 
41
- DeskApi.get '/api/v2/topics'
42
- DeskApi.post '/api/v2/topics', name: 'My new Topic', allow_questions: true
43
- DeskApi.patch '/api/v2/topics/1', name: 'Changed the Topic Name'
44
- DeskApi.delete '/api/v2/topics/1'
129
+ # ATTENTION: Cases can not be deleted!
130
+ begin
131
+ DeskApi.cases.first.delete
132
+ rescue DeskApi::Error::MethodNotAllowed => e
133
+ # too bad
134
+ end
45
135
  ```
136
+ ___
137
+ ### Getters & Setters
138
+
139
+ As you have seen in prior examples for each field on the resource we create a
140
+ getter and setter.
141
+
142
+ ```ruby
143
+ customer = DeskApi.customers.find(1)
46
144
 
47
- ## Working with Resources and Collections
145
+ puts customer.first_name
146
+ puts customer.last_name
147
+ puts customer.title
48
148
 
49
- The API supports RESTful resources and so does this wrapper. These resources are automatically discovered, meaning you can navigate around without having to worry about anything. We also support two finder methods `by_url` and `find`.
149
+ # for updates you can either use the setter or a hash
50
150
 
51
- ### Finders
151
+ customer.first_name = 'John'
152
+ customer.last_name = 'Doe'
153
+
154
+ updated_customer = customer.update title: 'Master of the Universe'
155
+
156
+ # users are not updatable
157
+ begin
158
+ user = DeskApi.users.first
159
+ user.update name: 'Not updateable'
160
+ rescue DeskApi::Error::MethodNotAllowed
161
+ # too bad
162
+ end
163
+ ```
164
+ ___
165
+ ### Find
166
+
167
+ The method `by_url` can be called on the client, for backwards compatability we
168
+ haven't yet removed it from the `DeskApi::Resource` but it will be removed once
169
+ we release v1 of this client. `by_url` will return a lazy loaded instance of the
170
+ resource.
171
+
172
+ ```ruby
173
+ first_reply = DeskApi.by_url '/api/v2/cases/1/replies/1'
174
+ ```
52
175
 
53
- The method `by_url` can be called on all `DeskApi::Resource` instances and will return a lazy loaded instance of the resource. Since the update to v0.5 of the API wrapper the `find` method can now be called on all `DeskApi::Resource` instances too. _Gotcha:_ It will rebuild the base path based on the resource/collection it is called on. So if you call it on the cases collection `DeskApi.cases.find 1` the path will look like this: `/api/v2/cases/:id`.
176
+ Since the update to v0.5 of the API wrapper the `find` method can now be called
177
+ on all `DeskApi::Resource` instances. _Gotcha:_ It will rebuild the base path
178
+ based on the resource/collection it is called on. So if you call it on the cases
179
+ collection `DeskApi.cases.find 1` the path will look like this:
180
+ `/api/v2/cases/:id`.
54
181
 
55
182
  | Method | Path |
56
183
  | ----------------------------------------------------------- | --------------------------- |
@@ -60,10 +187,11 @@ The method `by_url` can be called on all `DeskApi::Resource` instances and will
60
187
  | `DeskApi.cases.search(subject: 'Test').entries.find(1)` | `/api/v2/cases/1` |
61
188
  | `DeskApi.cases.entries.first.replies.find(1)` | `/api/v2/cases/1/replies/1` |
62
189
  | `DeskApi.cases.entries.first.replies.entries.first.find(1)` | `/api/v2/cases/1/replies/1` |
63
-
190
+ ___
64
191
  ### Pagination
65
192
 
66
- As mentioned above you can also navigate between resources and pages of collections. _Please Notice:_ `DeskApi.cases` doesn't behave like an `Array` any longer, it's just a `DeskApi::Resource` so links like `next`, `previous`, `first` and `last` can be called directly. However you'll have to request the `entries` before you can loop through all the records on the page.
193
+ As mentioned above you can also navigate between resources and pages of
194
+ collections.
67
195
 
68
196
  ```ruby
69
197
  cases = DeskApi.cases
@@ -86,10 +214,29 @@ last_page = previous_page.last
86
214
  # or go to the first page
87
215
  first_page = last_page.first
88
216
  ```
217
+ ___
218
+ ### `all` and `each_page`
219
+
220
+ As a recent addition we made it even easier to navigate through all the pages.
89
221
 
222
+ ```ruby
223
+ DeskApi.cases.all do |current_case, current_page_number|
224
+ # do something with the case
225
+ end
226
+
227
+ DeskApi.cases.each_page do |current_page, current_page_number|
228
+ # do something with the current page
229
+ end
230
+ ```
231
+
232
+ Both methods use the max `per_page` for the API endpoint for that particular
233
+ resource.
234
+ ___
90
235
  ### List params
91
236
 
92
- Some lists allow for additional params like [cases](http://dev.desk.com/API/cases/#list). This allows you to filter the cases endpoint by using a `company_id`, `customer_id` or `filter_id` list param.
237
+ Some lists allow for additional params like [cases](http://dev.desk.com/API/cases/#list).
238
+ This allows you to filter the cases endpoint by using a `company_id`,
239
+ `customer_id` or `filter_id` list param.
93
240
 
94
241
  ```ruby
95
242
  # fetch cases for the company with id 1
@@ -101,130 +248,124 @@ customers_cases = DeskApi.cases(customer_id: 1)
101
248
  # fetch cases for the filter with id 1
102
249
  filters_cases = DeskApi.cases(filter_id: 1)
103
250
  ```
104
-
251
+ ___
105
252
  ### Sorting
106
253
 
107
- A recent update on APIv2 now imposes a maximum page limit. This is why sorting got very important and now you can even sort the list endpoints like [cases](http://dev.desk.com/API/cases/#list).
254
+ There is a maximum `page` limit on some Desk.com API endpoints. As of right now
255
+ (May 2014) the limit is 500 for all endpoints that are limited, but please
256
+ consult the #list documentation for each resource:
257
+
258
+ - [Case list](http://dev.desk.com/API/cases#list)
259
+ - [Company Case list](http://dev.desk.com/API/companies#cases-list)
260
+ - [Customer Case list](http://dev.desk.com/API/customers#cases-list)
261
+ - [Filter Case list](http://dev.desk.com/API/filters#list-cases)
262
+ - [Case search](http://dev.desk.com/API/cases#search)
263
+ - [Customer search](http://dev.desk.com/API/customers#search)
264
+ - [Company search](http://dev.desk.com/API/companies#search)
265
+ - [Article search](http://dev.desk.com/API/articles#search)
266
+
267
+
268
+ To work around page limits, you can specify `sort_field` and `sort_direction`
108
269
 
109
270
  ```ruby
110
271
  # fetch cases sorted by updated_at direction desc
111
272
  sorted_cases = DeskApi.cases(sort_field: :updated_at, sort_direction: :desc)
112
273
  ```
113
-
274
+ ___
114
275
  ### Links
115
276
 
116
- Pagination is pretty obvious but the cool part about pagination or rather resources is the auto-linking. As soon as the resource has a link defined, it'll be navigatable:
277
+ Once a `DeskApi::Resource` has loaded, its [linked resources](http://dev.desk.com/API/using-the-api/#relationships) can be retrieved
278
+ by calling the linked resource as a method of the `DeskApi::Resource`, e.g.,
117
279
 
118
280
  ```ruby
119
- # get the customer of the first case of the first page
120
- customer = DeskApi.cases.entries.first.customer
121
-
122
- # who sent the first outbound reply of the first email
123
- user_name = DeskApi.cases.entries.select do |my_case|
124
- my_case.type == 'email'
125
- end.first.replies.entries.select do |reply|
126
- reply.direction == 'out'
127
- end.first.sent_by.name
281
+ # Get a ticket
282
+ ticket = DeskApi.cases.entries.first
283
+
284
+ # Get the ticket's assigned_user from the ticket
285
+ assigned_user = ticket.assigned_user
286
+
287
+ # Get the customer from the ticket
288
+ customer = ticket.customer
289
+
290
+ # Get the customer's company from the customer.
291
+ company = customer.company
292
+
293
+ # Getting the name of the user who sent the first outbound reply on a ticket
294
+ user_name = DeskApi.
295
+ cases.
296
+ entries.
297
+ select { |my_case| my_case.type == 'email' }.
298
+ first.
299
+ replies.
300
+ entries.select { |reply| reply.direction == 'out' }.
301
+ first.
302
+ sent_by.
303
+ name
128
304
  ```
129
-
305
+ ___
130
306
  ### Lazy loading
131
307
 
132
- Collections and resources in general are lazily loaded, meaning if you request the cases `DeskApi.cases` no actual request will be set off until you actually request data. Meaning only necessary requests are sent which will keep the request count low - [desk.com rate limit](http://dev.desk.com/API/using-the-api/#rate-limits).
308
+ Resources are lazy loaded. This means that requests are only sent when you
309
+ request data from the resource. This helps a lot with flying under the Desk.com
310
+ API [rate limit](http://dev.desk.com/API/using-the-api/#rate-limits). E.g.,
133
311
 
134
312
  ```ruby
135
313
  DeskApi.cases.page(10).per_page(50).entries.each do |my_case|
136
- # in this method chain `.entries' is the first method that acutally sends a request
314
+ # in this method chain, no HTTP request is fired until `.entries'
137
315
  end
138
316
 
139
317
  # however if you request the current page numer and the resource is not loaded
140
318
  # it'll send a request
141
319
  DeskApi.cases.page == 1
142
320
  ```
321
+ ___
322
+ ### Embedding
143
323
 
144
- ### Side loading
324
+ Some endpoints support [embedding](http://dev.desk.com/API/using-the-api/#embedding) related resources. E.g., when getting a list
325
+ of cases from `/api/v2/cases` you can embed the customer on each case by adding
326
+ `embed=` to the query string: `/api/v2/cases?embed=customer`
145
327
 
146
- APIv2 has a lot of great new features but the one I'm most excited about is side loading or embedding resources. You basically request one resource and tell the API to embed sub resources, eg. you need cases but also want to have the `assigned_user` - instead of requesting all cases and the `assigned_user` for each of those cases (30 cases = 31 API requests) you can now embed `assigned_user` into your cases list view (1 API request).
328
+ The client supports this: `tickets_and_customers = DeskApi.cases.embed(:customer)`
147
329
 
148
- Of course we had to bring this awesomeness into the API wrapper as soon as possible, so here you go:
330
+ Taking advantage of `.embed` is a great way to be conscious of the rate limit
331
+ and minimize necessary HTTP requests.
149
332
 
150
- ```ruby
151
- # fetch cases with their respective customers
152
- cases = DeskApi.cases.embed(:customer)
153
- customer = cases.first.customer
154
333
 
155
- # you can use this feature in finders too
156
- my_case = DeskApi.cases.find(1, embed: :customer)
157
- # OR
158
- my_case = DeskApi.cases.find(1, embed: [:customer, :assigned_user, :assigned_group, :message])
334
+ **Not using embedded resources**
335
+ ```ruby
336
+ tickets = DeskApi.cases.per_page(100).entries # HTTP request
337
+ tickets.each do |ticket|
338
+ puts ticket.customer.first_name # HTTP request (100 iterations)
339
+ end
159
340
 
160
- customer = my_case.customer
161
- assigned_user = my_case.assigned_user
162
- assigned_group = my_case.assigned_group
341
+ # Total Requests: 101
163
342
  ```
164
343
 
165
- ### Create, Update and Delete
166
-
167
- Of course we support creating, updating and deleting resources but not all resources can be deleted or updated or created, if that's the case for the resource you're trying to update, it'll throw a `DeskApi::Error::MethodNotAllowed` error. For ease of use and because we wanted to build as less business logic into the wrapper as possible, all of the methods are defined on each `DeskApi::Resource` and will be sent to desk.com. However the API might respond with an error if you do things that aren't supported.
168
-
344
+ **Using embedded resources**
169
345
  ```ruby
170
- # let's create an article
171
- new_article = DeskApi.articles.create({
172
- subject: 'Some Subject',
173
- body: 'Some Body',
174
- _links: {
175
- topic: DeskApi.topics.first.get_self
176
- }
177
- })
178
-
179
- # as you can see here a `Resource' always includes a method `.get_self'
180
- # which will return the link object to build relationships
181
-
182
- # updating the article
183
- updated_article = new_article.update subject: 'Updated Subject'
184
-
185
- # deleting the article
186
- if updated_article.delete == true
187
- # article has been deleted
346
+ tickets = DeskApi.cases.per_page(100).embed(:customer).entries # HTTP request
347
+ tickets.each do |ticket|
348
+ puts ticket.customer.first_name # No HTTP Request, customer is embedded
188
349
  end
189
350
 
190
- # ATTENTION: Cases can not be deleted!
191
- begin
192
- DeskApi.cases.first.delete
193
- rescue DeskApi::Error::MethodNotAllowed => e
194
- # too bad
195
- end
351
+ # Total Requests: 1
196
352
  ```
197
353
 
198
- ### Getters & Setters
199
-
200
- As you have seen in prior examples for each field on the resource we create a getter and setter.
201
-
354
+ **Using embedded resources in `find`**
202
355
  ```ruby
203
- customer = DeskApi.customers.find(1)
204
-
205
- puts customer.first_name
206
- puts customer.last_name
207
- puts customer.title
208
-
209
- # for updates you can either use the setter or a hash
210
-
211
- customer.first_name = 'John'
212
- customer.last_name = 'Doe'
213
-
214
- updated_customer = customer.update title: 'Master of the Universe'
356
+ my_case = DeskApi.cases.find(1, embed: :customer)
357
+ # OR
358
+ my_case = DeskApi.cases.find(1, embed: [:customer, :assigned_user, :assigned_group, :message])
215
359
 
216
- # users are not updatable
217
- begin
218
- user = DeskApi.users.first
219
- user.update name: 'Not updateable'
220
- rescue DeskApi::Error::MethodNotAllowed
221
- # too bad
222
- end
360
+ customer = my_case.customer
361
+ assigned_user = my_case.assigned_user
362
+ assigned_group = my_case.assigned_group
223
363
  ```
224
-
364
+ ___
225
365
  ### API Errors
226
366
 
227
- Sometimes the API is going to return errors, eg. Validation Error. In these cases we wrap the API error into a `DeskApi::Error`. Here are the common errors:
367
+ Sometimes the API is going to return errors, eg. Validation Error. In these
368
+ cases we wrap the API error into a `DeskApi::Error`. Here are the common errors:
228
369
 
229
370
  ```ruby
230
371
  DeskApi::Error::BadRequest #=> 400 Status
@@ -239,19 +380,32 @@ DeskApi::Error::UnprocessableEntity #=> 422 Status
239
380
  DeskApi::Error::TooManyRequests #=> 429 Status
240
381
  ```
241
382
 
242
- Please also have a look at all [desk.com API errors](http://dev.desk.com/API/using-the-api/#status-codes) and their respective meanings.
383
+ Please also have a look at all
384
+ [desk.com API errors](http://dev.desk.com/API/using-the-api/#status-codes) and
385
+ their respective meanings.
243
386
 
387
+ ___
244
388
  ## License
389
+ ___
245
390
 
246
391
  (The MIT License)
247
392
 
248
- Copyright (c) 2013 Thomas Stachl &lt;thomas@desk.com&gt;
249
-
250
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
251
-
252
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
253
-
254
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
255
-
256
- [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/tstachl/desk/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
257
-
393
+ Copyright (c) 2013-2014 Thomas Stachl <tstachl@salesforce.com>
394
+
395
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
396
+ this software and associated documentation files (the 'Software'), to deal in
397
+ the Software without restriction, including without limitation the rights to
398
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
399
+ the Software, and to permit persons to whom the Software is furnished to do so,
400
+ subject to the following conditions:
401
+
402
+ The above copyright notice and this permission notice shall be included in all
403
+ copies or substantial portions of the Software.
404
+
405
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
406
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
407
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
408
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
409
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
410
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
411
+ SOFTWARE.