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,857 @@
|
|
|
1
|
+
# Column Values in monday.com
|
|
2
|
+
|
|
3
|
+
This document explains the concept of column values, their types, formats, and why they work the way they do in the monday.com API.
|
|
4
|
+
|
|
5
|
+
## What are Column Values?
|
|
6
|
+
|
|
7
|
+
In monday.com, column values are the data stored in the cells of a board. Each item (row) has values for each column (field) defined on its board. Unlike traditional databases where column types are strictly defined, monday.com supports a rich variety of column types, each with its own value structure and behavior.
|
|
8
|
+
|
|
9
|
+
### The monday.com Data Model
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Board
|
|
13
|
+
├── Group 1
|
|
14
|
+
│ ├── Item A
|
|
15
|
+
│ │ ├── Status Column: "Done"
|
|
16
|
+
│ │ ├── Date Column: "2024-01-15"
|
|
17
|
+
│ │ └── Person Column: [User 123, User 456]
|
|
18
|
+
│ └── Item B
|
|
19
|
+
└── Group 2
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Each cell in this structure contains a column value. The structure and meaning of that value depends on the column type.
|
|
23
|
+
|
|
24
|
+
### Column Values vs Column Definitions
|
|
25
|
+
|
|
26
|
+
It's important to distinguish between:
|
|
27
|
+
|
|
28
|
+
- **Column definition**: The column itself (its ID, type, title, settings)
|
|
29
|
+
- **Column value**: The data stored in that column for a specific item
|
|
30
|
+
|
|
31
|
+
For example:
|
|
32
|
+
- Column definition: `{id: "status", type: "status", title: "Project Status"}`
|
|
33
|
+
- Column value: `{label: "In Progress", index: 1}`
|
|
34
|
+
|
|
35
|
+
## Column Types and Their Value Formats
|
|
36
|
+
|
|
37
|
+
monday.com supports numerous column types, each requiring a specific value format.
|
|
38
|
+
|
|
39
|
+
### Simple Column Types
|
|
40
|
+
|
|
41
|
+
Some column types store simple, straightforward values:
|
|
42
|
+
|
|
43
|
+
**Text**
|
|
44
|
+
```json
|
|
45
|
+
"This is a text value"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Number**
|
|
49
|
+
```json
|
|
50
|
+
"42"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Checkbox**
|
|
54
|
+
```json
|
|
55
|
+
{"checked": true}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Complex Column Types
|
|
59
|
+
|
|
60
|
+
Many column types have structured, complex values:
|
|
61
|
+
|
|
62
|
+
**Status**
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"label": "Done",
|
|
66
|
+
"index": 2
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
Contains both the display label and the index (position in status options).
|
|
70
|
+
|
|
71
|
+
**Date**
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"date": "2024-01-15",
|
|
75
|
+
"time": "14:30:00"
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
Supports date-only or date+time values.
|
|
79
|
+
|
|
80
|
+
**Person**
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"personsAndTeams": [
|
|
84
|
+
{"id": 12345, "kind": "person"},
|
|
85
|
+
{"id": 67890, "kind": "team"}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
Can reference multiple people and/or teams.
|
|
90
|
+
|
|
91
|
+
**Dropdown**
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"labels": ["Option 1", "Option 2"]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
Single or multiple selections depending on column settings.
|
|
98
|
+
|
|
99
|
+
**Link**
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"url": "https://example.com",
|
|
103
|
+
"text": "Example Website"
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
URL with optional display text.
|
|
107
|
+
|
|
108
|
+
**Phone**
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"phone": "+1-555-123-4567",
|
|
112
|
+
"countryShortName": "US"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
Phone number with country code.
|
|
116
|
+
|
|
117
|
+
**Email**
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"email": "user@example.com",
|
|
121
|
+
"text": "John Doe"
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
Email address with optional display name.
|
|
125
|
+
|
|
126
|
+
**Location**
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"lat": "37.7749",
|
|
130
|
+
"lng": "-122.4194",
|
|
131
|
+
"address": "San Francisco, CA"
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
Geographic coordinates and address.
|
|
135
|
+
|
|
136
|
+
**Timeline**
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"from": "2024-01-01",
|
|
140
|
+
"to": "2024-12-31"
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
Date range with start and end dates.
|
|
144
|
+
|
|
145
|
+
## Why Different Column Types Need Different JSON Structures
|
|
146
|
+
|
|
147
|
+
The structural diversity in column value formats reflects the semantic differences between data types.
|
|
148
|
+
|
|
149
|
+
### Semantic Richness
|
|
150
|
+
|
|
151
|
+
Each column type represents different real-world concepts:
|
|
152
|
+
|
|
153
|
+
- **Status**: Requires both a label (what users see) and an index (for ordering/grouping)
|
|
154
|
+
- **Person**: Must distinguish between individual users and teams, and support multiple assignments
|
|
155
|
+
- **Date**: Needs to handle date-only and date-time scenarios differently
|
|
156
|
+
- **Link**: Separates the destination URL from the display text
|
|
157
|
+
|
|
158
|
+
### Backend Processing
|
|
159
|
+
|
|
160
|
+
Different column types trigger different backend behaviors:
|
|
161
|
+
|
|
162
|
+
- **Person columns**: Trigger notifications to assigned users
|
|
163
|
+
- **Status columns**: Update board analytics and dashboards
|
|
164
|
+
- **Date columns**: Power timeline views and deadline reminders
|
|
165
|
+
- **Formula columns**: Recalculate when dependent values change
|
|
166
|
+
|
|
167
|
+
The value format provides the data needed for these behaviors.
|
|
168
|
+
|
|
169
|
+
### Validation Requirements
|
|
170
|
+
|
|
171
|
+
Each column type has unique validation needs:
|
|
172
|
+
|
|
173
|
+
- **Email**: Must validate email format
|
|
174
|
+
- **Phone**: Must validate phone number format and country code
|
|
175
|
+
- **Date**: Must validate date is valid and in correct format
|
|
176
|
+
- **Dropdown**: Must validate selection exists in column settings
|
|
177
|
+
|
|
178
|
+
The structured format enables server-side validation.
|
|
179
|
+
|
|
180
|
+
### UI Rendering
|
|
181
|
+
|
|
182
|
+
The monday.com interface renders each column type differently:
|
|
183
|
+
|
|
184
|
+
- **Status**: Colored labels with icons
|
|
185
|
+
- **Person**: Avatar images with names
|
|
186
|
+
- **Date**: Calendar picker
|
|
187
|
+
- **Timeline**: Gantt chart visualization
|
|
188
|
+
|
|
189
|
+
The value structure includes all information needed for rendering.
|
|
190
|
+
|
|
191
|
+
## Simple vs Complex Column Values
|
|
192
|
+
|
|
193
|
+
Column values exist on a spectrum from simple to complex.
|
|
194
|
+
|
|
195
|
+
### Simple Column Values
|
|
196
|
+
|
|
197
|
+
Types like text, number, and checkbox are "simple":
|
|
198
|
+
- Single primitive value or shallow object
|
|
199
|
+
- Minimal structure
|
|
200
|
+
- Easy to read and write
|
|
201
|
+
- Limited backend processing
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
"Simple text"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Complex Column Values
|
|
208
|
+
|
|
209
|
+
Types like person, board relation, and mirror are "complex":
|
|
210
|
+
- Deeply nested structures
|
|
211
|
+
- Multiple data points
|
|
212
|
+
- References to other entities
|
|
213
|
+
- Extensive backend processing
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"item_ids": [123, 456, 789],
|
|
218
|
+
"linkedPulseIds": [
|
|
219
|
+
{"linkedPulseId": 123},
|
|
220
|
+
{"linkedPulseId": 456}
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### The Complexity Spectrum
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
Simple Complex
|
|
229
|
+
├─────────┼─────────┼─────────┼─────────┼─────────┤
|
|
230
|
+
Text Number Status Person Board-Relation
|
|
231
|
+
Checkbox Date Dropdown Mirror
|
|
232
|
+
Link Timeline Formula
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Complexity affects:
|
|
236
|
+
- **API payload size**: Complex values require more data
|
|
237
|
+
- **Validation logic**: Complex values have more validation rules
|
|
238
|
+
- **Query performance**: Complex values may require joins or lookups
|
|
239
|
+
- **Update latency**: Complex values may trigger cascading updates
|
|
240
|
+
|
|
241
|
+
## Column IDs vs Column Titles
|
|
242
|
+
|
|
243
|
+
Understanding the difference between column IDs and titles is crucial for working with column values.
|
|
244
|
+
|
|
245
|
+
### Column Title
|
|
246
|
+
|
|
247
|
+
The title is the human-readable name displayed in the monday.com interface:
|
|
248
|
+
- "Project Status"
|
|
249
|
+
- "Due Date"
|
|
250
|
+
- "Assigned To"
|
|
251
|
+
|
|
252
|
+
Titles are:
|
|
253
|
+
- User-facing and editable
|
|
254
|
+
- Not guaranteed to be unique
|
|
255
|
+
- Can change at any time
|
|
256
|
+
- Localized in some cases
|
|
257
|
+
|
|
258
|
+
### Column ID
|
|
259
|
+
|
|
260
|
+
The ID is a unique identifier for the column:
|
|
261
|
+
- "status"
|
|
262
|
+
- "date4"
|
|
263
|
+
- "person"
|
|
264
|
+
|
|
265
|
+
IDs are:
|
|
266
|
+
- System-facing and stable
|
|
267
|
+
- Guaranteed unique within a board
|
|
268
|
+
- Generally don't change (though they can)
|
|
269
|
+
- Not localized
|
|
270
|
+
|
|
271
|
+
### Why IDs are Board-Specific
|
|
272
|
+
|
|
273
|
+
Column IDs are only unique within a board:
|
|
274
|
+
- Board A can have a column with ID "status"
|
|
275
|
+
- Board B can also have a column with ID "status"
|
|
276
|
+
- These are different columns with potentially different settings
|
|
277
|
+
|
|
278
|
+
This means:
|
|
279
|
+
- You cannot assume column ID "status" has the same meaning across boards
|
|
280
|
+
- When working with multiple boards, track board ID + column ID
|
|
281
|
+
- Column settings (like status options) are board-specific
|
|
282
|
+
|
|
283
|
+
### API Usage
|
|
284
|
+
|
|
285
|
+
The API uses column IDs, not titles:
|
|
286
|
+
|
|
287
|
+
```ruby
|
|
288
|
+
# Correct: Use column ID
|
|
289
|
+
client.item.change_column_value(
|
|
290
|
+
args: {
|
|
291
|
+
board_id: 123,
|
|
292
|
+
item_id: 456,
|
|
293
|
+
column_id: "status", # Column ID
|
|
294
|
+
value: '{"label": "Done"}'
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
# Incorrect: Cannot use column title
|
|
299
|
+
client.item.change_column_value(
|
|
300
|
+
args: {
|
|
301
|
+
column_id: "Project Status", # Won't work!
|
|
302
|
+
...
|
|
303
|
+
}
|
|
304
|
+
)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Finding Column IDs
|
|
308
|
+
|
|
309
|
+
To find column IDs:
|
|
310
|
+
1. Query the board's columns
|
|
311
|
+
2. Match by title to find the corresponding ID
|
|
312
|
+
3. Use the ID in subsequent operations
|
|
313
|
+
|
|
314
|
+
```ruby
|
|
315
|
+
# Get column information
|
|
316
|
+
response = client.board.query(
|
|
317
|
+
args: { ids: [123] },
|
|
318
|
+
select: [{ columns: ["id", "title", "type"] }]
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
# Find column ID by title
|
|
322
|
+
columns = response.dig("data", "boards", 0, "columns")
|
|
323
|
+
status_column = columns.find { |col| col["title"] == "Project Status" }
|
|
324
|
+
column_id = status_column["id"] # Use this ID
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## JSON Serialization Requirements
|
|
328
|
+
|
|
329
|
+
Column values are passed as JSON strings in the monday.com API, which has important implications.
|
|
330
|
+
|
|
331
|
+
### Why JSON Strings?
|
|
332
|
+
|
|
333
|
+
The API requires column values as JSON-encoded strings rather than native objects:
|
|
334
|
+
|
|
335
|
+
```ruby
|
|
336
|
+
# Correct: JSON string
|
|
337
|
+
value = '{"label": "Done"}'
|
|
338
|
+
|
|
339
|
+
# Incorrect: Ruby hash
|
|
340
|
+
value = {label: "Done"} # Won't work!
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Reasons for this design**:
|
|
344
|
+
|
|
345
|
+
1. **GraphQL limitations**: GraphQL mutations require static types, but column values vary by column type
|
|
346
|
+
2. **Flexibility**: JSON strings can represent any column type without defining dozens of input types
|
|
347
|
+
3. **Backward compatibility**: New column types can be added without API changes
|
|
348
|
+
4. **Validation**: Server can validate after parsing based on actual column type
|
|
349
|
+
|
|
350
|
+
### Serialization Process
|
|
351
|
+
|
|
352
|
+
When setting a column value:
|
|
353
|
+
|
|
354
|
+
1. **Construct**: Build a Ruby hash with the value structure
|
|
355
|
+
```ruby
|
|
356
|
+
value_hash = {label: "Done", index: 2}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
2. **Serialize**: Convert to JSON string
|
|
360
|
+
```ruby
|
|
361
|
+
value_json = value_hash.to_json
|
|
362
|
+
# => '{"label":"Done","index":2}'
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
3. **Send**: Pass the JSON string to the API
|
|
366
|
+
```ruby
|
|
367
|
+
client.item.change_column_value(
|
|
368
|
+
args: { column_id: "status", value: value_json }
|
|
369
|
+
)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Deserialization Process
|
|
373
|
+
|
|
374
|
+
When reading column values:
|
|
375
|
+
|
|
376
|
+
1. **Receive**: Get JSON string from API
|
|
377
|
+
```ruby
|
|
378
|
+
column_value = response.dig("data", "items", 0, "column_values", 0, "value")
|
|
379
|
+
# => '{"label":"Done","index":2}'
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
2. **Parse**: Convert from JSON string to Ruby hash
|
|
383
|
+
```ruby
|
|
384
|
+
value_hash = JSON.parse(column_value)
|
|
385
|
+
# => {"label"=>"Done", "index"=>2}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
3. **Use**: Access the parsed data
|
|
389
|
+
```ruby
|
|
390
|
+
label = value_hash["label"] # => "Done"
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Common Serialization Pitfalls
|
|
394
|
+
|
|
395
|
+
**Double encoding**:
|
|
396
|
+
```ruby
|
|
397
|
+
# Wrong: Double encoding
|
|
398
|
+
value = {label: "Done"}.to_json.to_json
|
|
399
|
+
# => '"{\"label\":\"Done\"}"' # Escaped quotes!
|
|
400
|
+
|
|
401
|
+
# Correct: Single encoding
|
|
402
|
+
value = {label: "Done"}.to_json
|
|
403
|
+
# => '{"label":"Done"}'
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**Symbol vs string keys**:
|
|
407
|
+
```ruby
|
|
408
|
+
# Both work, but consistency matters
|
|
409
|
+
{label: "Done"}.to_json # => '{"label":"Done"}'
|
|
410
|
+
{"label" => "Done"}.to_json # => '{"label":"Done"}'
|
|
411
|
+
|
|
412
|
+
# Parsing returns string keys
|
|
413
|
+
JSON.parse('{"label":"Done"}')
|
|
414
|
+
# => {"label"=>"Done"} # String keys, not symbols
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**Escaping**:
|
|
418
|
+
```ruby
|
|
419
|
+
# Special characters must be properly escaped
|
|
420
|
+
value = {text: 'Quote: "Hello"'}.to_json
|
|
421
|
+
# => '{"text":"Quote: \"Hello\""}'
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## change_value vs change_simple_value vs change_multiple_values
|
|
425
|
+
|
|
426
|
+
monday.com provides multiple methods for updating column values, each optimized for different scenarios.
|
|
427
|
+
|
|
428
|
+
### change_column_value
|
|
429
|
+
|
|
430
|
+
Updates a single column value on a single item:
|
|
431
|
+
|
|
432
|
+
```ruby
|
|
433
|
+
client.item.change_column_value(
|
|
434
|
+
args: {
|
|
435
|
+
board_id: 123,
|
|
436
|
+
item_id: 456,
|
|
437
|
+
column_id: "status",
|
|
438
|
+
value: '{"label": "Done"}'
|
|
439
|
+
}
|
|
440
|
+
)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Characteristics**:
|
|
444
|
+
- Most explicit and clear
|
|
445
|
+
- Requires full value structure
|
|
446
|
+
- Works with any column type
|
|
447
|
+
- Validates against column type
|
|
448
|
+
- Returns updated item
|
|
449
|
+
|
|
450
|
+
**Use when**:
|
|
451
|
+
- Updating complex column values
|
|
452
|
+
- Need full control over value structure
|
|
453
|
+
- Working with a single column
|
|
454
|
+
|
|
455
|
+
### change_simple_column_value
|
|
456
|
+
|
|
457
|
+
Simplified version for common column types:
|
|
458
|
+
|
|
459
|
+
```ruby
|
|
460
|
+
client.item.change_simple_column_value(
|
|
461
|
+
args: {
|
|
462
|
+
board_id: 123,
|
|
463
|
+
item_id: 456,
|
|
464
|
+
column_id: "text_column",
|
|
465
|
+
value: "Simple text" # Plain string, not JSON
|
|
466
|
+
}
|
|
467
|
+
)
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
**Characteristics**:
|
|
471
|
+
- Accepts plain strings for simple types
|
|
472
|
+
- Automatically handles JSON encoding
|
|
473
|
+
- Limited to simple column types (text, number)
|
|
474
|
+
- Less flexible than `change_column_value`
|
|
475
|
+
|
|
476
|
+
**Use when**:
|
|
477
|
+
- Updating text or number columns
|
|
478
|
+
- Value is a simple string or number
|
|
479
|
+
- Want simplified API
|
|
480
|
+
|
|
481
|
+
### change_multiple_column_values
|
|
482
|
+
|
|
483
|
+
Updates multiple columns on a single item in one request:
|
|
484
|
+
|
|
485
|
+
```ruby
|
|
486
|
+
client.item.change_multiple_column_values(
|
|
487
|
+
args: {
|
|
488
|
+
board_id: 123,
|
|
489
|
+
item_id: 456,
|
|
490
|
+
column_values: {
|
|
491
|
+
status: {label: "Done"},
|
|
492
|
+
date4: {date: "2024-01-15"},
|
|
493
|
+
person: {personsAndTeams: [{id: 12345, kind: "person"}]}
|
|
494
|
+
}.to_json
|
|
495
|
+
}
|
|
496
|
+
)
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
**Characteristics**:
|
|
500
|
+
- Updates multiple columns atomically
|
|
501
|
+
- More efficient than multiple single-column updates
|
|
502
|
+
- Reduces API calls and complexity
|
|
503
|
+
- Single validation and response
|
|
504
|
+
|
|
505
|
+
**Use when**:
|
|
506
|
+
- Updating several columns at once
|
|
507
|
+
- Creating items with initial values
|
|
508
|
+
- Want to minimize API requests
|
|
509
|
+
- Need atomic updates (all or nothing)
|
|
510
|
+
|
|
511
|
+
### Method Comparison
|
|
512
|
+
|
|
513
|
+
| Method | Columns per Call | Value Format | Complexity | Use Case |
|
|
514
|
+
|--------|-----------------|--------------|------------|----------|
|
|
515
|
+
| `change_column_value` | 1 | JSON string | Medium | Single column, any type |
|
|
516
|
+
| `change_simple_column_value` | 1 | Plain string | Low | Simple types only |
|
|
517
|
+
| `change_multiple_column_values` | Multiple | JSON string | Higher | Batch updates |
|
|
518
|
+
|
|
519
|
+
### Performance Implications
|
|
520
|
+
|
|
521
|
+
**Multiple single updates**:
|
|
522
|
+
```ruby
|
|
523
|
+
# 3 API calls
|
|
524
|
+
client.item.change_column_value(args: {column_id: "status", ...})
|
|
525
|
+
client.item.change_column_value(args: {column_id: "date4", ...})
|
|
526
|
+
client.item.change_column_value(args: {column_id: "person", ...})
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
**Single batch update**:
|
|
530
|
+
```ruby
|
|
531
|
+
# 1 API call
|
|
532
|
+
client.item.change_multiple_column_values(
|
|
533
|
+
args: {
|
|
534
|
+
column_values: {
|
|
535
|
+
status: {...},
|
|
536
|
+
date4: {...},
|
|
537
|
+
person: {...}
|
|
538
|
+
}.to_json
|
|
539
|
+
}
|
|
540
|
+
)
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
Batch updates:
|
|
544
|
+
- 3× fewer API calls
|
|
545
|
+
- 3× less authentication overhead
|
|
546
|
+
- Lower total complexity
|
|
547
|
+
- Faster total execution
|
|
548
|
+
- Atomic (all succeed or all fail)
|
|
549
|
+
|
|
550
|
+
## Column Value Validation
|
|
551
|
+
|
|
552
|
+
Validation of column values happens on the monday.com server, not in the API client.
|
|
553
|
+
|
|
554
|
+
### Server-Side Validation
|
|
555
|
+
|
|
556
|
+
When you submit a column value, monday.com validates:
|
|
557
|
+
|
|
558
|
+
1. **Type compatibility**: Value structure matches column type
|
|
559
|
+
2. **Required fields**: All necessary fields are present
|
|
560
|
+
3. **Value constraints**: Values are within allowed ranges/options
|
|
561
|
+
4. **Reference validity**: Referenced entities (users, boards, etc.) exist
|
|
562
|
+
5. **Permissions**: User has permission to set the value
|
|
563
|
+
|
|
564
|
+
### Why Server-Side?
|
|
565
|
+
|
|
566
|
+
- **Authoritative**: Board configuration is server-controlled
|
|
567
|
+
- **Dynamic**: Column settings can change
|
|
568
|
+
- **Security**: Client-side validation can be bypassed
|
|
569
|
+
- **Consistency**: Same validation for all API clients
|
|
570
|
+
- **Complex rules**: Some validation requires server data
|
|
571
|
+
|
|
572
|
+
### Validation Errors
|
|
573
|
+
|
|
574
|
+
Invalid column values return errors:
|
|
575
|
+
|
|
576
|
+
```ruby
|
|
577
|
+
# Invalid status label
|
|
578
|
+
client.item.change_column_value(
|
|
579
|
+
args: {
|
|
580
|
+
column_id: "status",
|
|
581
|
+
value: '{"label": "Invalid Status"}'
|
|
582
|
+
}
|
|
583
|
+
)
|
|
584
|
+
# Error: "Status label 'Invalid Status' does not exist"
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
```ruby
|
|
588
|
+
# Invalid date format
|
|
589
|
+
client.item.change_column_value(
|
|
590
|
+
args: {
|
|
591
|
+
column_id: "date4",
|
|
592
|
+
value: '{"date": "2024-13-45"}' # Invalid date
|
|
593
|
+
}
|
|
594
|
+
)
|
|
595
|
+
# Error: "Invalid date format"
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### Validation Strategy
|
|
599
|
+
|
|
600
|
+
Best practices for handling validation:
|
|
601
|
+
|
|
602
|
+
1. **Query column settings**: Fetch column configuration to know valid options
|
|
603
|
+
2. **Validate client-side**: Pre-validate when possible to avoid API calls
|
|
604
|
+
3. **Handle errors**: Catch and handle validation errors gracefully
|
|
605
|
+
4. **Test edge cases**: Test with boundary values and edge cases
|
|
606
|
+
5. **Monitor changes**: Watch for board configuration changes that affect validation
|
|
607
|
+
|
|
608
|
+
### Example: Status Column Validation
|
|
609
|
+
|
|
610
|
+
```ruby
|
|
611
|
+
# 1. Get valid status options
|
|
612
|
+
board = client.board.query(
|
|
613
|
+
args: { ids: [123] },
|
|
614
|
+
select: [{ columns: ["id", "settings_str"] }]
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
status_column = board.dig("data", "boards", 0, "columns")
|
|
618
|
+
.find { |c| c["id"] == "status" }
|
|
619
|
+
|
|
620
|
+
settings = JSON.parse(status_column["settings_str"])
|
|
621
|
+
valid_labels = settings["labels"].keys
|
|
622
|
+
# => ["Not Started", "In Progress", "Done"]
|
|
623
|
+
|
|
624
|
+
# 2. Validate before sending
|
|
625
|
+
label = "Done"
|
|
626
|
+
if valid_labels.include?(label)
|
|
627
|
+
client.item.change_column_value(
|
|
628
|
+
args: {
|
|
629
|
+
column_id: "status",
|
|
630
|
+
value: {label: label}.to_json
|
|
631
|
+
}
|
|
632
|
+
)
|
|
633
|
+
else
|
|
634
|
+
# Handle invalid label
|
|
635
|
+
puts "Invalid status: #{label}"
|
|
636
|
+
end
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
## Common Column Value Patterns
|
|
640
|
+
|
|
641
|
+
Certain patterns appear frequently when working with column values.
|
|
642
|
+
|
|
643
|
+
### Clearing a Column Value
|
|
644
|
+
|
|
645
|
+
To clear a column value, set it to an empty object or null:
|
|
646
|
+
|
|
647
|
+
```ruby
|
|
648
|
+
# Clear status column
|
|
649
|
+
client.item.change_column_value(
|
|
650
|
+
args: {
|
|
651
|
+
column_id: "status",
|
|
652
|
+
value: '{}'
|
|
653
|
+
}
|
|
654
|
+
)
|
|
655
|
+
|
|
656
|
+
# Clear text column
|
|
657
|
+
client.item.change_simple_column_value(
|
|
658
|
+
args: {
|
|
659
|
+
column_id: "text_column",
|
|
660
|
+
value: ""
|
|
661
|
+
}
|
|
662
|
+
)
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
### Copying Column Values Between Items
|
|
666
|
+
|
|
667
|
+
```ruby
|
|
668
|
+
# Get source item's column value
|
|
669
|
+
source = client.item.query(
|
|
670
|
+
args: { ids: [123] },
|
|
671
|
+
select: [{ column_values: ["id", "value"] }]
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
status_value = source.dig("data", "items", 0, "column_values")
|
|
675
|
+
.find { |cv| cv["id"] == "status" }["value"]
|
|
676
|
+
|
|
677
|
+
# Set on destination item
|
|
678
|
+
client.item.change_column_value(
|
|
679
|
+
args: {
|
|
680
|
+
item_id: 456,
|
|
681
|
+
column_id: "status",
|
|
682
|
+
value: status_value # Already JSON string
|
|
683
|
+
}
|
|
684
|
+
)
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Conditional Updates
|
|
688
|
+
|
|
689
|
+
```ruby
|
|
690
|
+
# Update only if current value meets condition
|
|
691
|
+
item = client.item.query(
|
|
692
|
+
args: { ids: [123] },
|
|
693
|
+
select: [{ column_values: ["id", "value"] }]
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
status = JSON.parse(
|
|
697
|
+
item.dig("data", "items", 0, "column_values")
|
|
698
|
+
.find { |cv| cv["id"] == "status" }["value"]
|
|
699
|
+
)
|
|
700
|
+
|
|
701
|
+
if status["label"] == "In Progress"
|
|
702
|
+
# Move to Done
|
|
703
|
+
client.item.change_column_value(
|
|
704
|
+
args: {
|
|
705
|
+
column_id: "status",
|
|
706
|
+
value: '{"label": "Done"}'
|
|
707
|
+
}
|
|
708
|
+
)
|
|
709
|
+
end
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### Bulk Updates Across Items
|
|
713
|
+
|
|
714
|
+
```ruby
|
|
715
|
+
# Update same column on multiple items
|
|
716
|
+
item_ids = [123, 456, 789]
|
|
717
|
+
value = '{"label": "Done"}'
|
|
718
|
+
|
|
719
|
+
item_ids.each do |item_id|
|
|
720
|
+
client.item.change_column_value(
|
|
721
|
+
args: {
|
|
722
|
+
item_id: item_id,
|
|
723
|
+
column_id: "status",
|
|
724
|
+
value: value
|
|
725
|
+
}
|
|
726
|
+
)
|
|
727
|
+
end
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
### Setting Values on Item Creation
|
|
731
|
+
|
|
732
|
+
```ruby
|
|
733
|
+
# Create item with initial column values
|
|
734
|
+
client.item.create(
|
|
735
|
+
args: {
|
|
736
|
+
board_id: 123,
|
|
737
|
+
item_name: "New Task",
|
|
738
|
+
column_values: {
|
|
739
|
+
status: {label: "Not Started"},
|
|
740
|
+
date4: {date: "2024-12-31"},
|
|
741
|
+
person: {
|
|
742
|
+
personsAndTeams: [
|
|
743
|
+
{id: 12345, kind: "person"}
|
|
744
|
+
]
|
|
745
|
+
}
|
|
746
|
+
}.to_json
|
|
747
|
+
}
|
|
748
|
+
)
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
## Why Column Values are Strings/JSON
|
|
752
|
+
|
|
753
|
+
The decision to represent column values as JSON strings rather than native types has deep architectural reasons.
|
|
754
|
+
|
|
755
|
+
### GraphQL Type System Constraints
|
|
756
|
+
|
|
757
|
+
GraphQL requires mutations to have statically-typed inputs:
|
|
758
|
+
|
|
759
|
+
```graphql
|
|
760
|
+
# GraphQL requires knowing exact type at schema definition time
|
|
761
|
+
mutation {
|
|
762
|
+
change_column_value(
|
|
763
|
+
column_id: "status",
|
|
764
|
+
value: StatusInput # Must be a defined input type
|
|
765
|
+
)
|
|
766
|
+
}
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
With 30+ column types, each with different structures:
|
|
770
|
+
- Defining 30+ input types would be complex
|
|
771
|
+
- Adding new column types would break API compatibility
|
|
772
|
+
- Clients would need to know all types
|
|
773
|
+
|
|
774
|
+
### JSON as Universal Type
|
|
775
|
+
|
|
776
|
+
Using JSON strings provides a universal interface:
|
|
777
|
+
|
|
778
|
+
```graphql
|
|
779
|
+
mutation {
|
|
780
|
+
change_column_value(
|
|
781
|
+
column_id: String!,
|
|
782
|
+
value: JSON! # Universal type
|
|
783
|
+
)
|
|
784
|
+
}
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
Benefits:
|
|
788
|
+
- Single input type for all column values
|
|
789
|
+
- New column types don't require schema changes
|
|
790
|
+
- Backward compatible
|
|
791
|
+
- Forward compatible
|
|
792
|
+
|
|
793
|
+
### Runtime Type Resolution
|
|
794
|
+
|
|
795
|
+
With JSON strings, monday.com can:
|
|
796
|
+
|
|
797
|
+
1. **Receive** the value as a string
|
|
798
|
+
2. **Parse** the JSON
|
|
799
|
+
3. **Look up** the column type from the database
|
|
800
|
+
4. **Validate** based on actual column type
|
|
801
|
+
5. **Process** type-specific logic
|
|
802
|
+
|
|
803
|
+
This allows dynamic, runtime type handling instead of static, compile-time types.
|
|
804
|
+
|
|
805
|
+
### Trade-off: Type Safety vs Flexibility
|
|
806
|
+
|
|
807
|
+
**Type safety (if native objects were used)**:
|
|
808
|
+
- Compile-time validation
|
|
809
|
+
- Better IDE autocomplete
|
|
810
|
+
- Catch errors earlier
|
|
811
|
+
- More complex API
|
|
812
|
+
|
|
813
|
+
**Flexibility (current JSON string approach)**:
|
|
814
|
+
- Runtime validation
|
|
815
|
+
- Limited IDE support
|
|
816
|
+
- Errors caught later
|
|
817
|
+
- Simpler API
|
|
818
|
+
|
|
819
|
+
monday.com chose flexibility to support its rapidly evolving column type system.
|
|
820
|
+
|
|
821
|
+
### Client Library Implications
|
|
822
|
+
|
|
823
|
+
The monday_ruby gem could provide typed wrappers:
|
|
824
|
+
|
|
825
|
+
```ruby
|
|
826
|
+
# Hypothetical typed wrapper (not currently implemented)
|
|
827
|
+
StatusValue.new(label: "Done", index: 2).to_json
|
|
828
|
+
# => '{"label":"Done","index":2}'
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
This would provide:
|
|
832
|
+
- Type safety in Ruby
|
|
833
|
+
- Validation before API call
|
|
834
|
+
- Better developer experience
|
|
835
|
+
- Documentation through code
|
|
836
|
+
|
|
837
|
+
But would require:
|
|
838
|
+
- Maintaining type definitions for all column types
|
|
839
|
+
- Updates when monday.com adds column types
|
|
840
|
+
- Additional abstraction layer
|
|
841
|
+
|
|
842
|
+
Currently, monday_ruby passes JSON strings directly, keeping the API thin and flexible.
|
|
843
|
+
|
|
844
|
+
## Conclusion
|
|
845
|
+
|
|
846
|
+
Column values are the core data model in monday.com, representing diverse types of information with varying structural complexity. Understanding column values requires grasping several key concepts:
|
|
847
|
+
|
|
848
|
+
- **Type diversity**: Different column types have different value structures reflecting their semantic meaning
|
|
849
|
+
- **JSON serialization**: Values are passed as JSON strings due to GraphQL constraints and flexibility requirements
|
|
850
|
+
- **Column identification**: Column IDs, not titles, are used for API operations and are board-specific
|
|
851
|
+
- **Multiple update methods**: Different methods (`change_column_value`, `change_simple_column_value`, `change_multiple_column_values`) optimize for different scenarios
|
|
852
|
+
- **Server-side validation**: monday.com validates column values based on board configuration and column settings
|
|
853
|
+
- **Common patterns**: Clearing values, copying between items, and bulk updates follow established patterns
|
|
854
|
+
|
|
855
|
+
The JSON string approach, while requiring extra serialization steps, provides the flexibility necessary for monday.com's rich and evolving column type system. The monday_ruby gem preserves this design while providing Ruby-friendly interfaces for building and parsing these values.
|
|
856
|
+
|
|
857
|
+
Understanding these concepts enables you to effectively work with monday.com's data model, choose the right update methods, handle validation properly, and build robust integrations.
|