monday_ruby 1.1.0 → 1.2.0
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.
- checksums.yaml +4 -4
- data/.env +1 -1
- data/.rubocop.yml +2 -1
- data/CHANGELOG.md +14 -0
- data/CONTRIBUTING.md +104 -0
- data/README.md +146 -142
- data/docs/.vitepress/config.mjs +255 -0
- data/docs/.vitepress/theme/index.js +4 -0
- data/docs/.vitepress/theme/style.css +43 -0
- data/docs/README.md +80 -0
- data/docs/explanation/architecture.md +507 -0
- data/docs/explanation/best-practices/errors.md +478 -0
- data/docs/explanation/best-practices/performance.md +1084 -0
- data/docs/explanation/best-practices/rate-limiting.md +630 -0
- data/docs/explanation/best-practices/testing.md +820 -0
- data/docs/explanation/column-values.md +857 -0
- data/docs/explanation/design.md +795 -0
- data/docs/explanation/graphql.md +356 -0
- data/docs/explanation/migration/v1.md +808 -0
- data/docs/explanation/pagination.md +447 -0
- data/docs/guides/advanced/batch.md +1274 -0
- data/docs/guides/advanced/complex-queries.md +1114 -0
- data/docs/guides/advanced/errors.md +818 -0
- data/docs/guides/advanced/pagination.md +934 -0
- data/docs/guides/advanced/rate-limiting.md +981 -0
- data/docs/guides/authentication.md +286 -0
- data/docs/guides/boards/create.md +386 -0
- data/docs/guides/boards/delete.md +405 -0
- data/docs/guides/boards/duplicate.md +511 -0
- data/docs/guides/boards/query.md +530 -0
- data/docs/guides/boards/update.md +453 -0
- data/docs/guides/columns/create.md +452 -0
- data/docs/guides/columns/metadata.md +492 -0
- data/docs/guides/columns/query.md +455 -0
- data/docs/guides/columns/update-multiple.md +459 -0
- data/docs/guides/columns/update-values.md +509 -0
- data/docs/guides/files/add-to-column.md +40 -0
- data/docs/guides/files/add-to-update.md +37 -0
- data/docs/guides/files/clear-column.md +33 -0
- data/docs/guides/first-request.md +285 -0
- data/docs/guides/folders/manage.md +750 -0
- data/docs/guides/groups/items.md +626 -0
- data/docs/guides/groups/manage.md +501 -0
- data/docs/guides/installation.md +169 -0
- data/docs/guides/items/create.md +493 -0
- data/docs/guides/items/delete.md +514 -0
- data/docs/guides/items/query.md +605 -0
- data/docs/guides/items/subitems.md +483 -0
- data/docs/guides/items/update.md +699 -0
- data/docs/guides/updates/manage.md +619 -0
- data/docs/guides/use-cases/dashboard.md +1421 -0
- data/docs/guides/use-cases/import.md +1962 -0
- data/docs/guides/use-cases/task-management.md +1381 -0
- data/docs/guides/workspaces/manage.md +502 -0
- data/docs/index.md +69 -0
- data/docs/package-lock.json +2468 -0
- data/docs/package.json +13 -0
- data/docs/reference/client.md +540 -0
- data/docs/reference/configuration.md +586 -0
- data/docs/reference/errors.md +693 -0
- data/docs/reference/resources/account.md +208 -0
- data/docs/reference/resources/activity-log.md +369 -0
- data/docs/reference/resources/board-view.md +359 -0
- data/docs/reference/resources/board.md +393 -0
- data/docs/reference/resources/column.md +543 -0
- data/docs/reference/resources/file.md +236 -0
- data/docs/reference/resources/folder.md +386 -0
- data/docs/reference/resources/group.md +507 -0
- data/docs/reference/resources/item.md +348 -0
- data/docs/reference/resources/subitem.md +267 -0
- data/docs/reference/resources/update.md +259 -0
- data/docs/reference/resources/workspace.md +213 -0
- data/docs/reference/response.md +560 -0
- data/docs/tutorial/first-integration.md +713 -0
- data/lib/monday/client.rb +24 -0
- data/lib/monday/configuration.rb +5 -0
- data/lib/monday/request.rb +15 -0
- data/lib/monday/resources/base.rb +4 -0
- data/lib/monday/resources/file.rb +56 -0
- data/lib/monday/util.rb +1 -0
- data/lib/monday/version.rb +1 -1
- metadata +87 -4
|
@@ -0,0 +1,1114 @@
|
|
|
1
|
+
# Complex Queries
|
|
2
|
+
|
|
3
|
+
Build advanced GraphQL queries to retrieve nested data, combine multiple resources, and optimize performance.
|
|
4
|
+
|
|
5
|
+
## Understanding Field Selection
|
|
6
|
+
|
|
7
|
+
The `select` parameter controls which fields are returned in the response. It supports both arrays and hashes for nested data.
|
|
8
|
+
|
|
9
|
+
### Array Syntax for Simple Fields
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
select: ["id", "name", "created_at"]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This retrieves only the specified fields from the resource.
|
|
16
|
+
|
|
17
|
+
### Hash Syntax for Nested Fields
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
select: [
|
|
21
|
+
"id",
|
|
22
|
+
"name",
|
|
23
|
+
{
|
|
24
|
+
board: ["id", "name"]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This retrieves the item's `id` and `name`, plus nested board information.
|
|
30
|
+
|
|
31
|
+
### How It Works
|
|
32
|
+
|
|
33
|
+
The `Util.format_select` method converts Ruby hashes into GraphQL field selection syntax:
|
|
34
|
+
|
|
35
|
+
- `["id", "name"]` becomes `id name`
|
|
36
|
+
- `{ board: ["id", "name"] }` becomes `board { id name }`
|
|
37
|
+
- `{ column_values: ["id", "text", "type"] }` becomes `column_values { id text type }`
|
|
38
|
+
|
|
39
|
+
## Nested Field Selection
|
|
40
|
+
|
|
41
|
+
Query items with deeply nested data structures.
|
|
42
|
+
|
|
43
|
+
### Query Items with Column Values
|
|
44
|
+
|
|
45
|
+
Retrieve items and their column data:
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
require "monday_ruby"
|
|
49
|
+
|
|
50
|
+
Monday.configure do |config|
|
|
51
|
+
config.token = ENV["MONDAY_TOKEN"]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
client = Monday::Client.new
|
|
55
|
+
|
|
56
|
+
response = client.item.query(
|
|
57
|
+
args: { ids: [987654321] },
|
|
58
|
+
select: [
|
|
59
|
+
"id",
|
|
60
|
+
"name",
|
|
61
|
+
"created_at",
|
|
62
|
+
{
|
|
63
|
+
column_values: ["id", "text", "type", "value"]
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if response.success?
|
|
69
|
+
item = response.body.dig("data", "items", 0)
|
|
70
|
+
|
|
71
|
+
puts "Item: #{item['name']}"
|
|
72
|
+
puts "\nColumn Values:"
|
|
73
|
+
|
|
74
|
+
item["column_values"].each do |col|
|
|
75
|
+
puts " #{col['id']}: #{col['text']} (#{col['type']})"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Example output:**
|
|
81
|
+
```
|
|
82
|
+
Item: Q4 Marketing Campaign
|
|
83
|
+
Column Values:
|
|
84
|
+
status: Done (color)
|
|
85
|
+
person: John Doe (people)
|
|
86
|
+
date4: 2024-12-31 (date)
|
|
87
|
+
text: High Priority (text)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Query Boards with Groups and Items
|
|
91
|
+
|
|
92
|
+
Retrieve complete board structure:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
response = client.board.query(
|
|
96
|
+
args: { ids: [1234567890] },
|
|
97
|
+
select: [
|
|
98
|
+
"id",
|
|
99
|
+
"name",
|
|
100
|
+
"description",
|
|
101
|
+
{
|
|
102
|
+
groups: [
|
|
103
|
+
"id",
|
|
104
|
+
"title",
|
|
105
|
+
"color",
|
|
106
|
+
{
|
|
107
|
+
items_page: {
|
|
108
|
+
items: ["id", "name", "state"]
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if response.success?
|
|
117
|
+
board = response.body.dig("data", "boards", 0)
|
|
118
|
+
|
|
119
|
+
puts "Board: #{board['name']}"
|
|
120
|
+
puts "Description: #{board['description']}"
|
|
121
|
+
puts "\nGroups:"
|
|
122
|
+
|
|
123
|
+
board["groups"].each do |group|
|
|
124
|
+
puts "\n #{group['title']} (#{group['color']})"
|
|
125
|
+
|
|
126
|
+
items = group.dig("items_page", "items") || []
|
|
127
|
+
puts " Items: #{items.length}"
|
|
128
|
+
|
|
129
|
+
items.first(3).each do |item|
|
|
130
|
+
puts " - #{item['name']} [#{item['state']}]"
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Example output:**
|
|
137
|
+
```
|
|
138
|
+
Board: Marketing Projects
|
|
139
|
+
Description: Track all marketing initiatives
|
|
140
|
+
|
|
141
|
+
Groups:
|
|
142
|
+
|
|
143
|
+
Q1 Planning (blue)
|
|
144
|
+
Items: 5
|
|
145
|
+
- Website Redesign [active]
|
|
146
|
+
- Email Campaign [active]
|
|
147
|
+
- Social Media Strategy [done]
|
|
148
|
+
|
|
149
|
+
Q2 Execution (green)
|
|
150
|
+
Items: 8
|
|
151
|
+
- Content Calendar [active]
|
|
152
|
+
- SEO Optimization [active]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Deep Nesting - Items with Subitems and Column Values
|
|
156
|
+
|
|
157
|
+
Retrieve items with their subitems and all column data:
|
|
158
|
+
|
|
159
|
+
```ruby
|
|
160
|
+
response = client.item.query(
|
|
161
|
+
args: { ids: [987654321] },
|
|
162
|
+
select: [
|
|
163
|
+
"id",
|
|
164
|
+
"name",
|
|
165
|
+
"state",
|
|
166
|
+
{
|
|
167
|
+
board: ["id", "name"],
|
|
168
|
+
group: ["id", "title"],
|
|
169
|
+
column_values: ["id", "text", "type"],
|
|
170
|
+
subitems: [
|
|
171
|
+
"id",
|
|
172
|
+
"name",
|
|
173
|
+
"state",
|
|
174
|
+
{
|
|
175
|
+
column_values: ["id", "text"]
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
if response.success?
|
|
183
|
+
item = response.body.dig("data", "items", 0)
|
|
184
|
+
board = item.dig("board")
|
|
185
|
+
group = item.dig("group")
|
|
186
|
+
|
|
187
|
+
puts "Item: #{item['name']}"
|
|
188
|
+
puts "Board: #{board['name']}"
|
|
189
|
+
puts "Group: #{group['title']}"
|
|
190
|
+
puts "State: #{item['state']}"
|
|
191
|
+
|
|
192
|
+
puts "\nColumn Values:"
|
|
193
|
+
item["column_values"].each do |col|
|
|
194
|
+
next if col["text"].nil? || col["text"].empty?
|
|
195
|
+
puts " #{col['id']}: #{col['text']}"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
puts "\nSubitems:"
|
|
199
|
+
item["subitems"].each do |subitem|
|
|
200
|
+
puts " - #{subitem['name']} [#{subitem['state']}]"
|
|
201
|
+
|
|
202
|
+
subitem["column_values"].each do |col|
|
|
203
|
+
next if col["text"].nil? || col["text"].empty?
|
|
204
|
+
puts " #{col['id']}: #{col['text']}"
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Query Multiple Resources
|
|
211
|
+
|
|
212
|
+
Combine different resource queries into a single request by making parallel calls or using custom GraphQL queries.
|
|
213
|
+
|
|
214
|
+
### Query Boards and Workspaces Together
|
|
215
|
+
|
|
216
|
+
Get workspace and board information in one flow:
|
|
217
|
+
|
|
218
|
+
```ruby
|
|
219
|
+
# First, get workspaces
|
|
220
|
+
workspace_response = client.workspace.query(
|
|
221
|
+
select: [
|
|
222
|
+
"id",
|
|
223
|
+
"name",
|
|
224
|
+
"description"
|
|
225
|
+
]
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
workspaces = workspace_response.body.dig("data", "workspaces")
|
|
229
|
+
|
|
230
|
+
# Then, get boards for each workspace
|
|
231
|
+
workspaces.each do |workspace|
|
|
232
|
+
board_response = client.board.query(
|
|
233
|
+
args: { workspace_ids: [workspace["id"]] },
|
|
234
|
+
select: [
|
|
235
|
+
"id",
|
|
236
|
+
"name",
|
|
237
|
+
{
|
|
238
|
+
groups: ["id", "title"]
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
boards = board_response.body.dig("data", "boards")
|
|
244
|
+
|
|
245
|
+
puts "\nWorkspace: #{workspace['name']}"
|
|
246
|
+
puts "Boards: #{boards.length}"
|
|
247
|
+
|
|
248
|
+
boards.each do |board|
|
|
249
|
+
puts " - #{board['name']} (#{board['groups'].length} groups)"
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Query Items from Multiple Boards
|
|
255
|
+
|
|
256
|
+
Retrieve items from different boards with specific fields:
|
|
257
|
+
|
|
258
|
+
```ruby
|
|
259
|
+
board_ids = [1234567890, 2345678901, 3456789012]
|
|
260
|
+
|
|
261
|
+
board_ids.each do |board_id|
|
|
262
|
+
response = client.board.items_page(
|
|
263
|
+
board_ids: board_id,
|
|
264
|
+
limit: 50,
|
|
265
|
+
select: [
|
|
266
|
+
"id",
|
|
267
|
+
"name",
|
|
268
|
+
{
|
|
269
|
+
board: ["id", "name"],
|
|
270
|
+
column_values: ["id", "text"]
|
|
271
|
+
}
|
|
272
|
+
]
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
if response.success?
|
|
276
|
+
board = response.body.dig("data", "boards", 0)
|
|
277
|
+
items = board.dig("items_page", "items")
|
|
278
|
+
|
|
279
|
+
puts "\nBoard: #{board_id}"
|
|
280
|
+
puts "Items: #{items.length}"
|
|
281
|
+
|
|
282
|
+
items.first(5).each do |item|
|
|
283
|
+
puts " - #{item['name']}"
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Combine Board, Group, and Item Queries
|
|
290
|
+
|
|
291
|
+
Get complete hierarchical data:
|
|
292
|
+
|
|
293
|
+
```ruby
|
|
294
|
+
# Get board with groups
|
|
295
|
+
board_response = client.board.query(
|
|
296
|
+
args: { ids: [1234567890] },
|
|
297
|
+
select: [
|
|
298
|
+
"id",
|
|
299
|
+
"name",
|
|
300
|
+
{
|
|
301
|
+
workspace: ["id", "name"],
|
|
302
|
+
groups: ["id", "title", "color"],
|
|
303
|
+
columns: ["id", "title", "type"]
|
|
304
|
+
}
|
|
305
|
+
]
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
board = board_response.body.dig("data", "boards", 0)
|
|
309
|
+
workspace = board.dig("workspace")
|
|
310
|
+
|
|
311
|
+
puts "Workspace: #{workspace['name']}"
|
|
312
|
+
puts "Board: #{board['name']}"
|
|
313
|
+
puts "\nColumns: #{board['columns'].length}"
|
|
314
|
+
board['columns'].each do |col|
|
|
315
|
+
puts " - #{col['title']} (#{col['type']})"
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
puts "\nGroups:"
|
|
319
|
+
board["groups"].each do |group|
|
|
320
|
+
# Get items for each group
|
|
321
|
+
items_response = client.group.items_page(
|
|
322
|
+
board_ids: board["id"],
|
|
323
|
+
group_ids: group["id"],
|
|
324
|
+
limit: 100,
|
|
325
|
+
select: [
|
|
326
|
+
"id",
|
|
327
|
+
"name",
|
|
328
|
+
"state",
|
|
329
|
+
{
|
|
330
|
+
column_values: ["id", "text"]
|
|
331
|
+
}
|
|
332
|
+
]
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
if items_response.success?
|
|
336
|
+
group_data = items_response.body.dig("data", "boards", 0, "groups", 0)
|
|
337
|
+
items = group_data.dig("items_page", "items") || []
|
|
338
|
+
|
|
339
|
+
puts "\n #{group['title']} (#{group['color']})"
|
|
340
|
+
puts " Items: #{items.length}"
|
|
341
|
+
|
|
342
|
+
items.first(3).each do |item|
|
|
343
|
+
puts " - #{item['name']} [#{item['state']}]"
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Advanced Filtering with query_params
|
|
350
|
+
|
|
351
|
+
Use complex filtering rules to find specific items.
|
|
352
|
+
|
|
353
|
+
### Single Rule Filter
|
|
354
|
+
|
|
355
|
+
Filter items by a single column value:
|
|
356
|
+
|
|
357
|
+
```ruby
|
|
358
|
+
response = client.board.items_page(
|
|
359
|
+
board_ids: 1234567890,
|
|
360
|
+
limit: 100,
|
|
361
|
+
query_params: {
|
|
362
|
+
rules: [
|
|
363
|
+
{ column_id: "status", compare_value: [1] }
|
|
364
|
+
],
|
|
365
|
+
operator: :and
|
|
366
|
+
},
|
|
367
|
+
select: [
|
|
368
|
+
"id",
|
|
369
|
+
"name",
|
|
370
|
+
{
|
|
371
|
+
column_values: ["id", "text"]
|
|
372
|
+
}
|
|
373
|
+
]
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
if response.success?
|
|
377
|
+
board = response.body.dig("data", "boards", 0)
|
|
378
|
+
items = board.dig("items_page", "items")
|
|
379
|
+
|
|
380
|
+
puts "Items with status index 1: #{items.length}"
|
|
381
|
+
end
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
::: tip Column Value Indices
|
|
385
|
+
Status column values use numeric indices (0, 1, 2, etc.) corresponding to their position in the status settings. Query your board's columns to see the available indices.
|
|
386
|
+
:::
|
|
387
|
+
|
|
388
|
+
### Multiple Rules with AND Logic
|
|
389
|
+
|
|
390
|
+
All rules must match:
|
|
391
|
+
|
|
392
|
+
```ruby
|
|
393
|
+
response = client.board.items_page(
|
|
394
|
+
board_ids: 1234567890,
|
|
395
|
+
limit: 100,
|
|
396
|
+
query_params: {
|
|
397
|
+
rules: [
|
|
398
|
+
{ column_id: "status", compare_value: [1] },
|
|
399
|
+
{ column_id: "priority", compare_value: [2] }
|
|
400
|
+
],
|
|
401
|
+
operator: :and
|
|
402
|
+
}
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
if response.success?
|
|
406
|
+
board = response.body.dig("data", "boards", 0)
|
|
407
|
+
items = board.dig("items_page", "items")
|
|
408
|
+
|
|
409
|
+
puts "High priority items with status=1: #{items.length}"
|
|
410
|
+
end
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Multiple Rules with OR Logic
|
|
414
|
+
|
|
415
|
+
Any rule can match:
|
|
416
|
+
|
|
417
|
+
```ruby
|
|
418
|
+
response = client.board.items_page(
|
|
419
|
+
board_ids: 1234567890,
|
|
420
|
+
limit: 100,
|
|
421
|
+
query_params: {
|
|
422
|
+
rules: [
|
|
423
|
+
{ column_id: "status", compare_value: [1] },
|
|
424
|
+
{ column_id: "status", compare_value: [2] }
|
|
425
|
+
],
|
|
426
|
+
operator: :or
|
|
427
|
+
},
|
|
428
|
+
select: ["id", "name"]
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
if response.success?
|
|
432
|
+
board = response.body.dig("data", "boards", 0)
|
|
433
|
+
items = board.dig("items_page", "items")
|
|
434
|
+
|
|
435
|
+
puts "Items with status 1 or 2: #{items.length}"
|
|
436
|
+
end
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Filter by Date Range
|
|
440
|
+
|
|
441
|
+
Filter items by date column:
|
|
442
|
+
|
|
443
|
+
```ruby
|
|
444
|
+
# Get items due in the next 7 days
|
|
445
|
+
today = Date.today
|
|
446
|
+
next_week = today + 7
|
|
447
|
+
|
|
448
|
+
response = client.board.items_page(
|
|
449
|
+
board_ids: 1234567890,
|
|
450
|
+
limit: 100,
|
|
451
|
+
query_params: {
|
|
452
|
+
rules: [
|
|
453
|
+
{
|
|
454
|
+
column_id: "date4", # Replace with your date column ID
|
|
455
|
+
compare_value: [today.to_s, next_week.to_s]
|
|
456
|
+
}
|
|
457
|
+
],
|
|
458
|
+
operator: :and
|
|
459
|
+
},
|
|
460
|
+
select: [
|
|
461
|
+
"id",
|
|
462
|
+
"name",
|
|
463
|
+
{
|
|
464
|
+
column_values: ["id", "text"]
|
|
465
|
+
}
|
|
466
|
+
]
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
if response.success?
|
|
470
|
+
board = response.body.dig("data", "boards", 0)
|
|
471
|
+
items = board.dig("items_page", "items")
|
|
472
|
+
|
|
473
|
+
puts "Items due in next 7 days: #{items.length}"
|
|
474
|
+
|
|
475
|
+
items.each do |item|
|
|
476
|
+
date_col = item["column_values"].find { |cv| cv["id"] == "date4" }
|
|
477
|
+
puts " - #{item['name']}: #{date_col&.dig('text')}"
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Combine Filtering and Pagination
|
|
483
|
+
|
|
484
|
+
Filter items and paginate through results:
|
|
485
|
+
|
|
486
|
+
```ruby
|
|
487
|
+
def fetch_filtered_items(client, board_id, query_params)
|
|
488
|
+
all_items = []
|
|
489
|
+
cursor = nil
|
|
490
|
+
|
|
491
|
+
loop do
|
|
492
|
+
response = client.board.items_page(
|
|
493
|
+
board_ids: board_id,
|
|
494
|
+
limit: 100,
|
|
495
|
+
cursor: cursor,
|
|
496
|
+
query_params: cursor.nil? ? query_params : nil, # Only pass on first request
|
|
497
|
+
select: [
|
|
498
|
+
"id",
|
|
499
|
+
"name",
|
|
500
|
+
{
|
|
501
|
+
column_values: ["id", "text"]
|
|
502
|
+
}
|
|
503
|
+
]
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
break unless response.success?
|
|
507
|
+
|
|
508
|
+
board = response.body.dig("data", "boards", 0)
|
|
509
|
+
items_page = board.dig("items_page")
|
|
510
|
+
items = items_page["items"]
|
|
511
|
+
|
|
512
|
+
break if items.empty?
|
|
513
|
+
|
|
514
|
+
all_items.concat(items)
|
|
515
|
+
cursor = items_page["cursor"]
|
|
516
|
+
|
|
517
|
+
break if cursor.nil?
|
|
518
|
+
|
|
519
|
+
puts "Fetched #{items.length} items, total: #{all_items.length}"
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
all_items
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# Usage: Get all high-priority items
|
|
526
|
+
items = fetch_filtered_items(
|
|
527
|
+
client,
|
|
528
|
+
1234567890,
|
|
529
|
+
{
|
|
530
|
+
rules: [{ column_id: "priority", compare_value: [2] }],
|
|
531
|
+
operator: :and
|
|
532
|
+
}
|
|
533
|
+
)
|
|
534
|
+
|
|
535
|
+
puts "\nTotal high-priority items: #{items.length}"
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
## Optimize Query Performance
|
|
539
|
+
|
|
540
|
+
Reduce complexity and improve response times.
|
|
541
|
+
|
|
542
|
+
### Select Only Needed Fields
|
|
543
|
+
|
|
544
|
+
**Bad - Over-fetching:**
|
|
545
|
+
```ruby
|
|
546
|
+
# Retrieves all default fields plus unnecessary nested data
|
|
547
|
+
response = client.item.query(
|
|
548
|
+
args: { ids: [987654321] },
|
|
549
|
+
select: [
|
|
550
|
+
"id",
|
|
551
|
+
"name",
|
|
552
|
+
"created_at",
|
|
553
|
+
"updated_at",
|
|
554
|
+
"creator_id",
|
|
555
|
+
"state",
|
|
556
|
+
"url",
|
|
557
|
+
{
|
|
558
|
+
board: ["id", "name", "description", "state", "url"],
|
|
559
|
+
group: ["id", "title", "color", "position"],
|
|
560
|
+
column_values: ["id", "text", "type", "value"],
|
|
561
|
+
updates: ["id", "body", "created_at", "creator"],
|
|
562
|
+
subitems: ["id", "name", "state", "created_at"]
|
|
563
|
+
}
|
|
564
|
+
]
|
|
565
|
+
)
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**Good - Minimal fields:**
|
|
569
|
+
```ruby
|
|
570
|
+
# Only retrieve what you need
|
|
571
|
+
response = client.item.query(
|
|
572
|
+
args: { ids: [987654321] },
|
|
573
|
+
select: [
|
|
574
|
+
"id",
|
|
575
|
+
"name",
|
|
576
|
+
{
|
|
577
|
+
column_values: ["id", "text"]
|
|
578
|
+
}
|
|
579
|
+
]
|
|
580
|
+
)
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### Use Pagination Instead of Large Queries
|
|
584
|
+
|
|
585
|
+
**Bad - Fetching all items at once:**
|
|
586
|
+
```ruby
|
|
587
|
+
# This can timeout or hit complexity limits
|
|
588
|
+
response = client.item.query(
|
|
589
|
+
args: { limit: 10000 }
|
|
590
|
+
)
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
**Good - Paginated approach:**
|
|
594
|
+
```ruby
|
|
595
|
+
response = client.board.items_page(
|
|
596
|
+
board_ids: 1234567890,
|
|
597
|
+
limit: 100 # Reasonable page size
|
|
598
|
+
)
|
|
599
|
+
|
|
600
|
+
items = response.body.dig("data", "boards", 0, "items_page", "items")
|
|
601
|
+
cursor = response.body.dig("data", "boards", 0, "items_page", "cursor")
|
|
602
|
+
|
|
603
|
+
# Fetch next page if needed
|
|
604
|
+
if cursor
|
|
605
|
+
next_response = client.board.items_page(
|
|
606
|
+
board_ids: 1234567890,
|
|
607
|
+
cursor: cursor
|
|
608
|
+
)
|
|
609
|
+
end
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Avoid Nested Loops of Queries
|
|
613
|
+
|
|
614
|
+
**Bad - N+1 query problem:**
|
|
615
|
+
```ruby
|
|
616
|
+
# Gets boards, then queries each board's items separately
|
|
617
|
+
boards_response = client.board.query
|
|
618
|
+
boards = boards_response.body.dig("data", "boards")
|
|
619
|
+
|
|
620
|
+
boards.each do |board|
|
|
621
|
+
# This creates N additional queries!
|
|
622
|
+
items_response = client.board.items_page(board_ids: board["id"])
|
|
623
|
+
items = items_response.body.dig("data", "boards", 0, "items_page", "items")
|
|
624
|
+
puts "#{board['name']}: #{items.length} items"
|
|
625
|
+
end
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
**Good - Batch query with nested selection:**
|
|
629
|
+
```ruby
|
|
630
|
+
# Get items in the initial query (for small datasets)
|
|
631
|
+
response = client.board.query(
|
|
632
|
+
args: { ids: [1234567890, 2345678901] },
|
|
633
|
+
select: [
|
|
634
|
+
"id",
|
|
635
|
+
"name",
|
|
636
|
+
{
|
|
637
|
+
items_page: {
|
|
638
|
+
items: ["id", "name"]
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
]
|
|
642
|
+
)
|
|
643
|
+
|
|
644
|
+
boards = response.body.dig("data", "boards")
|
|
645
|
+
boards.each do |board|
|
|
646
|
+
items = board.dig("items_page", "items") || []
|
|
647
|
+
puts "#{board['name']}: #{items.length} items"
|
|
648
|
+
end
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### Limit Column Value Queries
|
|
652
|
+
|
|
653
|
+
**Bad - Getting all column data:**
|
|
654
|
+
```ruby
|
|
655
|
+
response = client.item.query(
|
|
656
|
+
args: { ids: [987654321] },
|
|
657
|
+
select: [
|
|
658
|
+
"id",
|
|
659
|
+
"name",
|
|
660
|
+
{
|
|
661
|
+
column_values: ["id", "text", "type", "value", "additional_info"]
|
|
662
|
+
}
|
|
663
|
+
]
|
|
664
|
+
)
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
**Good - Only needed column fields:**
|
|
668
|
+
```ruby
|
|
669
|
+
response = client.item.query(
|
|
670
|
+
args: { ids: [987654321] },
|
|
671
|
+
select: [
|
|
672
|
+
"id",
|
|
673
|
+
"name",
|
|
674
|
+
{
|
|
675
|
+
column_values: ["id", "text"] # Just what you need
|
|
676
|
+
}
|
|
677
|
+
]
|
|
678
|
+
)
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
## Working with Related Data
|
|
682
|
+
|
|
683
|
+
Navigate relationships between boards, groups, items, and other resources.
|
|
684
|
+
|
|
685
|
+
### Board → Groups → Items → Column Values
|
|
686
|
+
|
|
687
|
+
Complete hierarchy traversal:
|
|
688
|
+
|
|
689
|
+
```ruby
|
|
690
|
+
# Get board with groups
|
|
691
|
+
board_response = client.board.query(
|
|
692
|
+
args: { ids: [1234567890] },
|
|
693
|
+
select: [
|
|
694
|
+
"id",
|
|
695
|
+
"name",
|
|
696
|
+
{
|
|
697
|
+
groups: ["id", "title"]
|
|
698
|
+
}
|
|
699
|
+
]
|
|
700
|
+
)
|
|
701
|
+
|
|
702
|
+
board = board_response.body.dig("data", "boards", 0)
|
|
703
|
+
|
|
704
|
+
puts "Board: #{board['name']}\n\n"
|
|
705
|
+
|
|
706
|
+
# For each group, get items with column values
|
|
707
|
+
board["groups"].each do |group|
|
|
708
|
+
items_response = client.group.items_page(
|
|
709
|
+
board_ids: board["id"],
|
|
710
|
+
group_ids: group["id"],
|
|
711
|
+
limit: 50,
|
|
712
|
+
select: [
|
|
713
|
+
"id",
|
|
714
|
+
"name",
|
|
715
|
+
{
|
|
716
|
+
column_values: ["id", "text", "type"]
|
|
717
|
+
}
|
|
718
|
+
]
|
|
719
|
+
)
|
|
720
|
+
|
|
721
|
+
if items_response.success?
|
|
722
|
+
group_data = items_response.body.dig("data", "boards", 0, "groups", 0)
|
|
723
|
+
items = group_data.dig("items_page", "items") || []
|
|
724
|
+
|
|
725
|
+
puts "Group: #{group['title']}"
|
|
726
|
+
puts "Items: #{items.length}\n"
|
|
727
|
+
|
|
728
|
+
items.first(3).each do |item|
|
|
729
|
+
puts " Item: #{item['name']}"
|
|
730
|
+
|
|
731
|
+
item["column_values"].each do |col|
|
|
732
|
+
next if col["text"].nil? || col["text"].empty?
|
|
733
|
+
puts " - #{col['id']}: #{col['text']} (#{col['type']})"
|
|
734
|
+
end
|
|
735
|
+
puts ""
|
|
736
|
+
end
|
|
737
|
+
end
|
|
738
|
+
end
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
### Workspace → Folders → Boards
|
|
742
|
+
|
|
743
|
+
Navigate organizational structure:
|
|
744
|
+
|
|
745
|
+
```ruby
|
|
746
|
+
# Get workspaces
|
|
747
|
+
workspace_response = client.workspace.query(
|
|
748
|
+
select: [
|
|
749
|
+
"id",
|
|
750
|
+
"name",
|
|
751
|
+
"description"
|
|
752
|
+
]
|
|
753
|
+
)
|
|
754
|
+
|
|
755
|
+
workspaces = workspace_response.body.dig("data", "workspaces")
|
|
756
|
+
|
|
757
|
+
workspaces.each do |workspace|
|
|
758
|
+
puts "\nWorkspace: #{workspace['name']}"
|
|
759
|
+
|
|
760
|
+
# Get boards in this workspace
|
|
761
|
+
boards_response = client.board.query(
|
|
762
|
+
args: { workspace_ids: [workspace["id"]] },
|
|
763
|
+
select: [
|
|
764
|
+
"id",
|
|
765
|
+
"name",
|
|
766
|
+
"description",
|
|
767
|
+
{
|
|
768
|
+
groups: ["id", "title"]
|
|
769
|
+
}
|
|
770
|
+
]
|
|
771
|
+
)
|
|
772
|
+
|
|
773
|
+
boards = boards_response.body.dig("data", "boards") || []
|
|
774
|
+
|
|
775
|
+
puts "Boards: #{boards.length}\n"
|
|
776
|
+
|
|
777
|
+
boards.each do |board|
|
|
778
|
+
puts " - #{board['name']}"
|
|
779
|
+
puts " Groups: #{board['groups'].length}"
|
|
780
|
+
end
|
|
781
|
+
end
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
### Item → Subitems → Updates
|
|
785
|
+
|
|
786
|
+
Get item with all related data:
|
|
787
|
+
|
|
788
|
+
```ruby
|
|
789
|
+
response = client.item.query(
|
|
790
|
+
args: { ids: [987654321] },
|
|
791
|
+
select: [
|
|
792
|
+
"id",
|
|
793
|
+
"name",
|
|
794
|
+
"created_at",
|
|
795
|
+
{
|
|
796
|
+
board: ["id", "name"],
|
|
797
|
+
group: ["id", "title"],
|
|
798
|
+
creator: ["id", "name", "email"],
|
|
799
|
+
subitems: [
|
|
800
|
+
"id",
|
|
801
|
+
"name",
|
|
802
|
+
"state",
|
|
803
|
+
{
|
|
804
|
+
column_values: ["id", "text"]
|
|
805
|
+
}
|
|
806
|
+
],
|
|
807
|
+
updates: [
|
|
808
|
+
"id",
|
|
809
|
+
"body",
|
|
810
|
+
"created_at",
|
|
811
|
+
{
|
|
812
|
+
creator: ["name"]
|
|
813
|
+
}
|
|
814
|
+
]
|
|
815
|
+
}
|
|
816
|
+
]
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
if response.success?
|
|
820
|
+
item = response.body.dig("data", "items", 0)
|
|
821
|
+
|
|
822
|
+
puts "Item: #{item['name']}"
|
|
823
|
+
puts "Board: #{item.dig('board', 'name')}"
|
|
824
|
+
puts "Group: #{item.dig('group', 'title')}"
|
|
825
|
+
puts "Creator: #{item.dig('creator', 'name')}"
|
|
826
|
+
puts "Created: #{item['created_at']}\n"
|
|
827
|
+
|
|
828
|
+
puts "\nSubitems (#{item['subitems'].length}):"
|
|
829
|
+
item["subitems"].each do |subitem|
|
|
830
|
+
puts " - #{subitem['name']} [#{subitem['state']}]"
|
|
831
|
+
end
|
|
832
|
+
|
|
833
|
+
puts "\nUpdates (#{item['updates'].length}):"
|
|
834
|
+
item["updates"].first(5).each do |update|
|
|
835
|
+
creator = update.dig("creator", "name")
|
|
836
|
+
puts " [#{update['created_at']}] #{creator}:"
|
|
837
|
+
puts " #{update['body']}\n\n"
|
|
838
|
+
end
|
|
839
|
+
end
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
## Custom Select Patterns
|
|
843
|
+
|
|
844
|
+
Advanced field selection techniques.
|
|
845
|
+
|
|
846
|
+
### Mixing Arrays and Hashes
|
|
847
|
+
|
|
848
|
+
Combine simple and nested fields:
|
|
849
|
+
|
|
850
|
+
```ruby
|
|
851
|
+
select: [
|
|
852
|
+
# Simple fields
|
|
853
|
+
"id",
|
|
854
|
+
"name",
|
|
855
|
+
"created_at",
|
|
856
|
+
"state",
|
|
857
|
+
|
|
858
|
+
# Nested fields with hash syntax
|
|
859
|
+
{
|
|
860
|
+
board: ["id", "name", "url"],
|
|
861
|
+
group: ["id", "title"],
|
|
862
|
+
creator: ["name", "email"]
|
|
863
|
+
},
|
|
864
|
+
|
|
865
|
+
# More simple fields
|
|
866
|
+
"url"
|
|
867
|
+
]
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
### Deeply Nested Structures
|
|
871
|
+
|
|
872
|
+
Multiple levels of nesting:
|
|
873
|
+
|
|
874
|
+
```ruby
|
|
875
|
+
response = client.board.query(
|
|
876
|
+
args: { ids: [1234567890] },
|
|
877
|
+
select: [
|
|
878
|
+
"id",
|
|
879
|
+
"name",
|
|
880
|
+
{
|
|
881
|
+
workspace: [
|
|
882
|
+
"id",
|
|
883
|
+
"name"
|
|
884
|
+
],
|
|
885
|
+
groups: [
|
|
886
|
+
"id",
|
|
887
|
+
"title",
|
|
888
|
+
"color",
|
|
889
|
+
{
|
|
890
|
+
items_page: {
|
|
891
|
+
items: [
|
|
892
|
+
"id",
|
|
893
|
+
"name",
|
|
894
|
+
{
|
|
895
|
+
column_values: ["id", "text"],
|
|
896
|
+
subitems: [
|
|
897
|
+
"id",
|
|
898
|
+
"name",
|
|
899
|
+
{
|
|
900
|
+
column_values: ["id", "text"]
|
|
901
|
+
}
|
|
902
|
+
]
|
|
903
|
+
}
|
|
904
|
+
]
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
]
|
|
908
|
+
}
|
|
909
|
+
]
|
|
910
|
+
)
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
### Conditional Field Selection
|
|
914
|
+
|
|
915
|
+
Select fields based on resource type:
|
|
916
|
+
|
|
917
|
+
```ruby
|
|
918
|
+
def query_with_details(client, item_ids, include_updates: false)
|
|
919
|
+
fields = [
|
|
920
|
+
"id",
|
|
921
|
+
"name",
|
|
922
|
+
{
|
|
923
|
+
board: ["id", "name"],
|
|
924
|
+
column_values: ["id", "text"]
|
|
925
|
+
}
|
|
926
|
+
]
|
|
927
|
+
|
|
928
|
+
# Conditionally add updates
|
|
929
|
+
if include_updates
|
|
930
|
+
fields << {
|
|
931
|
+
updates: ["id", "body", "created_at"]
|
|
932
|
+
}
|
|
933
|
+
end
|
|
934
|
+
|
|
935
|
+
client.item.query(
|
|
936
|
+
args: { ids: item_ids },
|
|
937
|
+
select: fields
|
|
938
|
+
)
|
|
939
|
+
end
|
|
940
|
+
|
|
941
|
+
# Usage
|
|
942
|
+
response = query_with_details(client, [987654321], include_updates: true)
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
### Reusable Field Definitions
|
|
946
|
+
|
|
947
|
+
Create reusable field sets:
|
|
948
|
+
|
|
949
|
+
```ruby
|
|
950
|
+
# Define common field sets
|
|
951
|
+
BASIC_ITEM_FIELDS = ["id", "name", "created_at"].freeze
|
|
952
|
+
|
|
953
|
+
ITEM_WITH_BOARD = [
|
|
954
|
+
*BASIC_ITEM_FIELDS,
|
|
955
|
+
{
|
|
956
|
+
board: ["id", "name"]
|
|
957
|
+
}
|
|
958
|
+
].freeze
|
|
959
|
+
|
|
960
|
+
ITEM_WITH_COLUMNS = [
|
|
961
|
+
*BASIC_ITEM_FIELDS,
|
|
962
|
+
{
|
|
963
|
+
column_values: ["id", "text", "type"]
|
|
964
|
+
}
|
|
965
|
+
].freeze
|
|
966
|
+
|
|
967
|
+
FULL_ITEM_FIELDS = [
|
|
968
|
+
*BASIC_ITEM_FIELDS,
|
|
969
|
+
"state",
|
|
970
|
+
"url",
|
|
971
|
+
{
|
|
972
|
+
board: ["id", "name"],
|
|
973
|
+
group: ["id", "title"],
|
|
974
|
+
column_values: ["id", "text", "type"],
|
|
975
|
+
creator: ["name", "email"]
|
|
976
|
+
}
|
|
977
|
+
].freeze
|
|
978
|
+
|
|
979
|
+
# Use them in queries
|
|
980
|
+
response = client.item.query(
|
|
981
|
+
args: { ids: [987654321] },
|
|
982
|
+
select: FULL_ITEM_FIELDS
|
|
983
|
+
)
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
## Complete Example
|
|
987
|
+
|
|
988
|
+
Comprehensive complex query combining multiple techniques:
|
|
989
|
+
|
|
990
|
+
```ruby
|
|
991
|
+
require "monday_ruby"
|
|
992
|
+
require "dotenv/load"
|
|
993
|
+
|
|
994
|
+
Monday.configure do |config|
|
|
995
|
+
config.token = ENV["MONDAY_TOKEN"]
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
client = Monday::Client.new
|
|
999
|
+
|
|
1000
|
+
# Get board with complete structure
|
|
1001
|
+
board_response = client.board.query(
|
|
1002
|
+
args: {
|
|
1003
|
+
ids: [1234567890],
|
|
1004
|
+
state: :active
|
|
1005
|
+
},
|
|
1006
|
+
select: [
|
|
1007
|
+
"id",
|
|
1008
|
+
"name",
|
|
1009
|
+
"description",
|
|
1010
|
+
{
|
|
1011
|
+
workspace: ["id", "name"],
|
|
1012
|
+
columns: ["id", "title", "type"],
|
|
1013
|
+
groups: ["id", "title", "color"]
|
|
1014
|
+
}
|
|
1015
|
+
]
|
|
1016
|
+
)
|
|
1017
|
+
|
|
1018
|
+
unless board_response.success?
|
|
1019
|
+
puts "Failed to fetch board"
|
|
1020
|
+
exit 1
|
|
1021
|
+
end
|
|
1022
|
+
|
|
1023
|
+
board = board_response.body.dig("data", "boards", 0)
|
|
1024
|
+
|
|
1025
|
+
puts "\n" + "=" * 70
|
|
1026
|
+
puts "BOARD: #{board['name']}"
|
|
1027
|
+
puts "=" * 70
|
|
1028
|
+
puts "Workspace: #{board.dig('workspace', 'name')}"
|
|
1029
|
+
puts "Description: #{board['description']}"
|
|
1030
|
+
puts "\nColumns (#{board['columns'].length}):"
|
|
1031
|
+
board['columns'].each do |col|
|
|
1032
|
+
puts " - #{col['title']} (#{col['type']})"
|
|
1033
|
+
end
|
|
1034
|
+
|
|
1035
|
+
puts "\n" + "-" * 70
|
|
1036
|
+
|
|
1037
|
+
# For each group, get filtered items
|
|
1038
|
+
board['groups'].each do |group|
|
|
1039
|
+
puts "\nGROUP: #{group['title']} (#{group['color']})"
|
|
1040
|
+
|
|
1041
|
+
# Get items with filters
|
|
1042
|
+
items_response = client.group.items_page(
|
|
1043
|
+
board_ids: board["id"],
|
|
1044
|
+
group_ids: group["id"],
|
|
1045
|
+
limit: 100,
|
|
1046
|
+
query_params: {
|
|
1047
|
+
rules: [
|
|
1048
|
+
{ column_id: "status", compare_value: [1] }
|
|
1049
|
+
],
|
|
1050
|
+
operator: :and
|
|
1051
|
+
},
|
|
1052
|
+
select: [
|
|
1053
|
+
"id",
|
|
1054
|
+
"name",
|
|
1055
|
+
"state",
|
|
1056
|
+
"created_at",
|
|
1057
|
+
{
|
|
1058
|
+
column_values: ["id", "text", "type"],
|
|
1059
|
+
creator: ["name", "email"],
|
|
1060
|
+
subitems: ["id", "name", "state"]
|
|
1061
|
+
}
|
|
1062
|
+
]
|
|
1063
|
+
)
|
|
1064
|
+
|
|
1065
|
+
next unless items_response.success?
|
|
1066
|
+
|
|
1067
|
+
group_data = items_response.body.dig("data", "boards", 0, "groups", 0)
|
|
1068
|
+
items = group_data.dig("items_page", "items") || []
|
|
1069
|
+
cursor = group_data.dig("items_page", "cursor")
|
|
1070
|
+
|
|
1071
|
+
puts "Items with status=1: #{items.length}"
|
|
1072
|
+
|
|
1073
|
+
items.first(5).each do |item|
|
|
1074
|
+
creator = item.dig("creator")
|
|
1075
|
+
subitems_count = item["subitems"].length
|
|
1076
|
+
|
|
1077
|
+
puts "\n Item: #{item['name']}"
|
|
1078
|
+
puts " State: #{item['state']}"
|
|
1079
|
+
puts " Created: #{item['created_at']}"
|
|
1080
|
+
puts " Creator: #{creator&.dig('name')} (#{creator&.dig('email')})"
|
|
1081
|
+
puts " Subitems: #{subitems_count}"
|
|
1082
|
+
|
|
1083
|
+
# Show column values
|
|
1084
|
+
puts " Columns:"
|
|
1085
|
+
item["column_values"].each do |col|
|
|
1086
|
+
next if col["text"].nil? || col["text"].empty?
|
|
1087
|
+
puts " #{col['id']}: #{col['text']}"
|
|
1088
|
+
end
|
|
1089
|
+
end
|
|
1090
|
+
|
|
1091
|
+
if cursor
|
|
1092
|
+
puts "\n [More items available - use cursor for pagination]"
|
|
1093
|
+
end
|
|
1094
|
+
end
|
|
1095
|
+
|
|
1096
|
+
puts "\n" + "=" * 70
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
## Performance Tips
|
|
1100
|
+
|
|
1101
|
+
1. **Request only what you need**: Minimize fields in `select` to reduce response size
|
|
1102
|
+
2. **Use pagination**: Always use `items_page` for large datasets instead of `items`
|
|
1103
|
+
3. **Batch queries**: Combine related data in single queries when possible
|
|
1104
|
+
4. **Cache results**: Store frequently accessed data to reduce API calls
|
|
1105
|
+
5. **Filter server-side**: Use `query_params` instead of fetching all items and filtering in Ruby
|
|
1106
|
+
6. **Monitor complexity**: monday.com has complexity limits - simpler queries are faster
|
|
1107
|
+
7. **Use cursors**: Cursor-based pagination is more efficient than offset-based
|
|
1108
|
+
|
|
1109
|
+
## Next Steps
|
|
1110
|
+
|
|
1111
|
+
- [Pagination guide](/guides/advanced/pagination)
|
|
1112
|
+
- [Error handling](/guides/advanced/errors)
|
|
1113
|
+
- [Rate limiting strategies](/guides/advanced/rate-limiting)
|
|
1114
|
+
- [Batch operations](/guides/advanced/batch)
|