notion_ruby_mapping 0.1.4 → 0.2.2

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Guardfile +1 -1
  3. data/README.md +514 -267
  4. data/env.yml.sample +8 -0
  5. data/lib/notion_ruby_mapping/base.rb +47 -36
  6. data/lib/notion_ruby_mapping/checkbox_property.rb +26 -0
  7. data/lib/notion_ruby_mapping/created_by_property.rb +21 -0
  8. data/lib/notion_ruby_mapping/created_time_property.rb +20 -0
  9. data/lib/notion_ruby_mapping/database.rb +14 -8
  10. data/lib/notion_ruby_mapping/date_base_property.rb +40 -38
  11. data/lib/notion_ruby_mapping/date_property.rb +42 -18
  12. data/lib/notion_ruby_mapping/email_property.rb +30 -1
  13. data/lib/notion_ruby_mapping/files_property.rb +40 -0
  14. data/lib/notion_ruby_mapping/formula_property.rb +18 -0
  15. data/lib/notion_ruby_mapping/last_edited_by_property.rb +21 -0
  16. data/lib/notion_ruby_mapping/last_edited_time_property.rb +20 -0
  17. data/lib/notion_ruby_mapping/list.rb +46 -2
  18. data/lib/notion_ruby_mapping/mention_object.rb +49 -0
  19. data/lib/notion_ruby_mapping/multi_select_property.rb +25 -6
  20. data/lib/notion_ruby_mapping/notion_cache.rb +137 -53
  21. data/lib/notion_ruby_mapping/number_property.rb +13 -8
  22. data/lib/notion_ruby_mapping/page.rb +11 -2
  23. data/lib/notion_ruby_mapping/payload.rb +12 -4
  24. data/lib/notion_ruby_mapping/people_property.rb +38 -0
  25. data/lib/notion_ruby_mapping/phone_number_property.rb +30 -1
  26. data/lib/notion_ruby_mapping/property.rb +79 -43
  27. data/lib/notion_ruby_mapping/property_cache.rb +31 -12
  28. data/lib/notion_ruby_mapping/query.rb +5 -2
  29. data/lib/notion_ruby_mapping/relation_property.rb +37 -0
  30. data/lib/notion_ruby_mapping/rich_text_object.rb +74 -0
  31. data/lib/notion_ruby_mapping/rich_text_property.rb +18 -0
  32. data/lib/notion_ruby_mapping/rollup_property.rb +29 -0
  33. data/lib/notion_ruby_mapping/select_property.rb +12 -6
  34. data/lib/notion_ruby_mapping/text_object.rb +89 -0
  35. data/lib/notion_ruby_mapping/text_property.rb +61 -0
  36. data/lib/notion_ruby_mapping/title_property.rb +18 -0
  37. data/lib/notion_ruby_mapping/url_property.rb +30 -1
  38. data/lib/notion_ruby_mapping/user_object.rb +38 -0
  39. data/lib/notion_ruby_mapping/version.rb +2 -1
  40. data/lib/notion_ruby_mapping.rb +3 -3
  41. data/notion_ruby_mapping.gemspec +3 -1
  42. metadata +40 -7
data/README.md CHANGED
@@ -1,44 +1,67 @@
1
- # NotionRubyMapping
1
+ # notion_ruby_mapping
2
2
 
3
3
  Notion Ruby mapping is currently under development.
4
4
 
5
5
  Development note is here. → [Idea note of "notion_ruby_mapping"](https://www.notion.so/hkob/Idea-note-of-notion_ruby_mapping-3b0a3bb3c171438a830f9579d41df501)
6
6
 
7
7
  ## Table of Contents
8
- - [NotionRubyMapping](#notionrubymapping)
8
+
9
+
10
+ <!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
11
+
12
+ <!-- code_chunk_output -->
13
+
14
+ - [notion\_ruby\_mapping](#notion_ruby_mapping)
9
15
  - [Table of Contents](#table-of-contents)
10
16
  - [1. Installation](#1-installation)
11
17
  - [2. Example code](#2-example-code)
12
- - [3. Usage](#3-usage)
18
+ - [2.1 Set icon to all icon unsettled pages](#21-set-icon-to-all-icon-unsettled-pages)
19
+ - [2.2 Renumbering pages](#22-renumbering-pages)
20
+ - [2.3 Change title](#23-change-title)
21
+ - [Pattern 1 (replace existing text partially)](#pattern-1-replace-existing-text-partially)
22
+ - [Pattern 2 (replace all text)](#pattern-2-replace-all-text)
23
+ - [3. Preparation](#3-preparation)
13
24
  - [3.1 Create a New Integration](#31-create-a-new-integration)
14
25
  - [3.2 Create client](#32-create-client)
15
- - [3.3 Retrieve a database](#33-retrieve-a-database)
16
- - [3.4 Retrieve a page](#34-retrieve-a-page)
17
- - [3.5 Query a database](#35-query-a-database)
18
- - [3.5.1 A simple example](#351-a-simple-example)
19
- - [3.5.2 Property classes](#352-property-classes)
20
- - [3.5.3 Query object generator of property objects](#353-query-object-generator-of-property-objects)
21
- - [3.5.4 Complex conditions](#354-complex-conditions)
22
- - [3.5.5 Sort criteria](#355-sort-criteria)
23
- - [3.6 Access the database or page values and properties](#36-access-the-database-or-page-values-and-properties)
24
- - [3.7 Set icon (Database / Page)](#37-set-icon-database--page)
25
- - [3.8 Update page property values](#38-update-page-property-values)
26
- - [3.8.1 Assign property and update it (fastest: one API call only)](#381-assign-property-and-update-it-fastest-one-api-call-only)
27
- - [3.8.2 Update the loaded page (easy but slow: two API calls)](#382-update-the-loaded-page-easy-but-slow-two-api-calls)
28
- - [3.8.3 Update the unloaded page with auto-load (easy but slow: two API calls)](#383-update-the-unloaded-page-with-auto-load-easy-but-slow-two-api-calls)
29
- - [3.8.4 Explanation of how to update each property](#384-explanation-of-how-to-update-each-property)
30
- - [3.8.4.1 NumberProperty](#3841-numberproperty)
31
- - [3.8.4.2 SelectProperty](#3842-selectproperty)
32
- - [3.8.4.3 MultiSelectProperty](#3843-multiselectproperty)
33
- - [3.8.4.4 DateProperty](#3844-dateproperty)
34
- - [3.9 Iteration of list object](#39-iteration-of-list-object)
35
- - [4. ChangeLog](#4-changelog)
36
- - [5. Contributing](#5-contributing)
37
- - [6. License](#6-license)
38
- - [7. Code of Conduct](#7-code-of-conduct)
39
- - [8. Acknowledgements](#8-acknowledgements)
40
-
41
- <!-- @import "[TOC]" {cmd="toc" depthFrom=2 depthTo=4 orderedList=false} -->
26
+ - [4. Usage](#4-usage)
27
+ - [4.1 Page](#41-page)
28
+ - [4.1.1 Retrieve a page](#411-retrieve-a-page)
29
+ - [4.1.2 Update page properties](#412-update-page-properties)
30
+ - [4.1.3 Update other page information](#413-update-other-page-information)
31
+ - [4.1.4 other methods](#414-other-methods)
32
+ - [4.2 Page](#42-page)
33
+ - [4.2.1 Retrieve a database](#421-retrieve-a-database)
34
+ - [4.2.2 Query a database](#422-query-a-database)
35
+ - [4.2.2.1 Complex conditions](#4221-complex-conditions)
36
+ - [4.2.2.2 Sort criteria](#4222-sort-criteria)
37
+ - [4.2.3 Update database](#423-update-database)
38
+ - [4.3 List class](#43-list-class)
39
+ - [4.4 Block class](#44-block-class)
40
+ - [4.5 Property classes](#45-property-classes)
41
+ - [4.5.1 How to obtain Property object](#451-how-to-obtain-property-object)
42
+ - [4.5.2 Query object generator of property objects](#452-query-object-generator-of-property-objects)
43
+ - [4.5.3 create or update values for Page properties](#453-create-or-update-values-for-page-properties)
44
+ - [4.5.3.1 NumberProperty](#4531-numberproperty)
45
+ - [4.5.3.2 SelectProperty](#4532-selectproperty)
46
+ - [4.5.3.3 MultiSelectProperty](#4533-multiselectproperty)
47
+ - [4.5.3.4 DateProperty](#4534-dateproperty)
48
+ - [4.5.3.4 UrlProperty](#4534-urlproperty)
49
+ - [4.5.3.5 EmailProperty](#4535-emailproperty)
50
+ - [4.5.3.6 PhoneNumberProperty](#4536-phonenumberproperty)
51
+ - [4.5.3.7 PeopleProperty](#4537-peopleproperty)
52
+ - [4.5.3.8 TitleProperty, RichTextProperty](#4538-titleproperty-richtextproperty)
53
+ - [4.5.3.9 CheckboxProperty](#4539-checkboxproperty)
54
+ - [4.5.3.10 EmailProperty](#45310-emailproperty)
55
+ - [4.5.3.11 FilesProperty](#45311-filesproperty)
56
+ - [4.5.3.12 RelationProperty](#45312-relationproperty)
57
+ - [6. ChangeLog](#6-changelog)
58
+ - [6. Contributing](#6-contributing)
59
+ - [7. License](#7-license)
60
+ - [8. Code of Conduct](#8-code-of-conduct)
61
+ - [9. Acknowledgements](#9-acknowledgements)
62
+
63
+ <!-- /code_chunk_output -->
64
+
42
65
 
43
66
  ## 1. Installation
44
67
 
@@ -50,15 +73,22 @@ gem 'notion_ruby_mapping'
50
73
 
51
74
  And then execute:
52
75
 
53
- $ bundle install
76
+ ```shell
77
+ bundle install
78
+ ```
54
79
 
55
80
  Or install it yourself as:
56
81
 
57
- $ gem install notion_ruby_mapping
82
+ ```shell
83
+ gem install notion_ruby_mapping
84
+ ```
58
85
 
59
86
  ## 2. Example code
60
87
 
88
+ ### 2.1 Set icon to all icon unsettled pages
89
+
61
90
  The following code sets a "💿" icon on all unset pages in the database.
91
+
62
92
  ```Ruby
63
93
  require "notion_ruby_mapping"
64
94
 
@@ -69,8 +99,13 @@ database_id = ENV["DATABASE_ID"]
69
99
 
70
100
  NotionCache.instance.create_client token
71
101
 
72
- Database.query(database_id).each do |page|
73
- p page.set_icon(emoji: "💿").id unless page.icon
102
+ db = Database.new id: database_id
103
+ db.query_database.each do |page|
104
+ unless page.icon
105
+ page.set_icon(emoji: "💿")
106
+ page.save
107
+ p page.id
108
+ end
74
109
  end
75
110
  ```
76
111
 
@@ -78,19 +113,50 @@ end
78
113
  |---|---|
79
114
  |![Before execution](images/pre_set_icon.png)|![After execution](images/post_set_icon.png)|
80
115
 
116
+ ### 2.2 Renumbering pages
117
+
81
118
  The following code sets serial numbers to the pages whose title is not empty in ascending order of titles.
119
+
82
120
  ```Ruby
83
- tp = RichTextProperty.new("TextTitle")
84
- Database.query(database_id, tp.filter_is_not_empty.ascending(tp)).each.with_index(1) do |page, index|
121
+ db = Database.new id: database_id, assign: [RichTextProperty, "TextTitle"]
122
+ tp = db.properties["TextTitle"]
123
+ query = tp.filter_is_not_empty.ascending(tp)
124
+ db.query_database(tp.filter_is_not_empty.ascending(tp)).each.with_index(1) do |page, index|
85
125
  page.properties["NumberTitle"].number = index
86
- page.update
126
+ page.save
87
127
  end
88
128
  ```
129
+
89
130
  | After execution |
90
131
  |-----------------------------------------------|
91
132
  | ![After exuecution](images/serial_number.png) |
92
133
 
93
- ## 3. Usage
134
+ ### 2.3 Change title
135
+
136
+ The following code update the page title.
137
+
138
+ #### Pattern 1 (replace existing text partially)
139
+
140
+ ```Ruby
141
+ page = Page.find page_id # API access
142
+ print page.title # -> ABC\nDEF
143
+ tp = page.properties["Title"]
144
+ tp[1].text = "GHI"
145
+ page.save # API access
146
+ print page.title # -> ABC\nGHI
147
+ ```
148
+
149
+ #### Pattern 2 (replace all text)
150
+
151
+ ```Ruby
152
+ page = Page.new id: page_id, assign: [TitleProperty, "Title"]
153
+ tp = page.properties["Title"]
154
+ tp << TextObject.new("JKL")
155
+ page.save # API access
156
+ print page.title # -> JKL
157
+ ```
158
+
159
+ ## 3. Preparation
94
160
 
95
161
  ### 3.1 Create a New Integration
96
162
 
@@ -99,176 +165,152 @@ Please check [Notion documentation](https://developers.notion.com/docs#getting-s
99
165
  ### 3.2 Create client
100
166
 
101
167
  Please create a client (notion-ruby-client) before you use the following class.
168
+
102
169
  ```Ruby
103
170
  NotionCache.instance.create_client ENV["NOTION_API_TOKEN"]
104
171
  ```
105
172
 
106
- ### 3.3 Retrieve a database
173
+ ## 4. Usage
174
+
175
+ ### 4.1 Page
176
+
177
+ #### 4.1.1 Retrieve a page
107
178
 
108
- Database.find(id) creates a Database object from the results of Notion API.
179
+ `Page.find(id)` creates a Page object with `retrieving page API`.
180
+ The created object has page information generated from the JSON response.
109
181
 
110
182
  ```Ruby
111
- db = Database.find("c37a2c66-e3aa-4a0d-a447-73de3b80c253")
183
+ page = Page.find "c01166c6-13ae-45cb-b968-18b4ef2f5a77" # Notion API call
112
184
  ```
113
185
 
114
- Database.new(id) creates a Database object without accessing to Notion.
115
- If you want to retrieve the contents after creation, please use a `reload` method.
186
+ `Page.new(id)` creates a Page object without the Notion API.
187
+ Since Page.new does not acquire property information, so you need to assign yourself.
116
188
 
117
189
  ```Ruby
118
- db = Database.new("c37a2c66-e3aa-4a0d-a447-73de3b80c253")
119
- db.reload
190
+ # Assign some properties for update manually
191
+ # The argument of assign keyword is Array with the multiple pairs of PropertyClass and Property name
192
+ page = Page.new id: "c01166c6-13ae-45cb-b968-18b4ef2f5a77",
193
+ assign: [TitleProperty, "Title", NumberProperty, "NumberTitle"]
120
194
  ```
121
195
 
122
- ### 3.4 Retrieve a page
196
+ #### 4.1.2 Update page properties
123
197
 
124
- Page.find(id) creates a Page object from the results of Notion API.
198
+ Page properties with values can be obtained from the retrieved page using `find`.
199
+ On the other hand, Page properties without values can be obtained from the property assigned page.
125
200
 
126
201
  ```Ruby
127
- page = Page.find("c01166c6-13ae-45cb-b968-18b4ef2f5a77")
202
+ tp = page.properties["Title"] # TitleProperty
203
+ np = page.properties["Number"] # NumberProperty
128
204
  ```
129
205
 
130
- Page.new(id) creates a Page object without accessing to Notion.
131
- If you want to retrieve the contents after creation, please use a `reload` method.
206
+ Each property object can change values using corresponded methods.
207
+ After changing value, `will_update` flag of the property object also set to true.
208
+ These methods are explained in the section of each property object class.
132
209
 
133
210
  ```Ruby
134
- page = Page.new("c01166c6-13ae-45cb-b968-18b4ef2f5a77")
135
- page.reload
211
+ to = tp[1] # TitleProperty has Array of TextObject
212
+ to.text = "ABC" # TextObject can set text by ".text="
213
+ # or tp[1].text = "ABC"
214
+
215
+ np.number = 3.14159
216
+ page.save # Notion API call
136
217
  ```
137
218
 
138
- ### 3.5 Query a database
219
+ After update some properties, `page.save` method sends `Notion API` and replace the page information using the response of API.
139
220
 
140
- #### 3.5.1 A simple example
221
+ ```Ruby
222
+ page.update # Notion API call
223
+ ```
224
+
225
+ #### 4.1.3 Update other page information
226
+
227
+ `page.set_icon` can change the page icon using emoji or external url.
228
+
229
+ [Breaking change on v0.2.2] `page.set_icon` has no longer calling the Notion API.
230
+ Please use `page.save` after `page.set_icon` if you want to update or create the page.
141
231
 
142
- Gets a List object of Page objects contained in the database.
143
- You can obtain filtered and ordered pages using Query object.
144
232
  ```Ruby
145
- Database.query("c37a2c66-e3aa-4a0d-a447-73de3b80c253") # retrieves all pages
146
- Database.query("c37a2c66-e3aa-4a0d-a447-73de3b80c253", query) # retrieves using query
233
+ # both methods call Notion API
234
+ obj.set_icon emoji: "💿" # set emoji
235
+ obj.save
236
+
237
+ obj.set_icon url: "https://cdn.profile-image.st-hatena.com/users/hkob/profile.png" # set external url
238
+ obj.save
147
239
  ```
148
240
 
149
- Query object can be generated from the following Property objects.
150
- For example, in order to obtain the pages whose title starts with "A" and ordered by ascending,
151
- the following code can be used.
241
+ #### 4.1.4 other methods
242
+
243
+ - `page.save` call Notion API, and so on and replace object information.
244
+ - `page.new_record?` returns true if the page was generated by `create_child_page`.
245
+ - `page.title` returns plain_text string of `Title`.
246
+ - `page.icon` returns JSON hash for the page icon.
247
+ - `page[key]` returns a hash or an array object except "properties".
248
+
249
+ ### 4.2 Database
250
+
251
+ #### 4.2.1 Retrieve a database
252
+
253
+ `Database.find(id)` creates a Database object with `retrieving database API`.
254
+ The created object has database information generated from the JSON response.
255
+
152
256
  ```Ruby
153
- tp = TitleProperty.new "Title"
154
- query = tp.filter_starts_with("A").ascending(tp)
155
- pages = Database.query database_id, query
257
+ db = Database.find("c37a2c66-e3aa-4a0d-a447-73de3b80c253") # Notion API call
156
258
  ```
157
259
 
158
- #### 3.5.2 Property classes
260
+ `Database.new(id)` creates a Database object without the Notion API.
261
+ Since Database.new does not acquire property information, so you need to assign yourself.
159
262
 
160
- There are the following 17 XXXProperty classes corresponding to Notion databases.
161
- They are child classes of a `Property` class
162
- and these constructor method has a common form where the first argument is the property name.
163
263
  ```Ruby
164
- xp = XXXProperty.new "property name"
264
+ # assign some properties for update manually
265
+ db = Database.new id: "c37a2c66-e3aa-4a0d-a447-73de3b80c253",
266
+ assign: [TitleProperty, "Title", NumberProperty, "NumberTitle"]
165
267
  ```
166
268
 
167
- 1. TitleProperty
168
- 2. RichTextProperty
169
- 3. UrlProperty
170
- 4. EmailProperty
171
- 5. PhoneNumberProperty
172
- 6. NumberProperty
173
- 7. CheckboxProperty
174
- 8. SelectProperty
175
- 9. MultiSelectProperty
176
- 10. PeopleProperty
177
- 11. CreatedByProperty
178
- 12. LastEditedByProperty
179
- 13. DateProperty
180
- 14. CreatedTimeProperty
181
- 15. LastEditedTimeProperty
182
- 16. FilesProperty
183
- 17. FormulaProperty
269
+ #### 4.2.2 Query a database
184
270
 
185
- #### 3.5.3 Query object generator of property objects
271
+ `db.query_database` obtains a List object with Page objects contained in the database.
272
+ You can obtain filtered and ordered pages using Query object.
186
273
 
187
- The following methods for the Property objects generate a query object.
188
- - TitleProperty, RichTextProperty, UrlProperty, EmailProperty, PhoneNumberProperty
189
- - filter_equals(value)
190
- - filter_does_not_equal(value)
191
- - filter_contains(value)
192
- - filter_does_not_contain(value)
193
- - filter_starts_with(value)
194
- - filter_ends_with(value)
195
- - filter_is_empty
196
- - filter_is_not_empty
197
- - NumberProperty
198
- - filter_equals(value)
199
- - filter_does_not_equal(value)
200
- - filter_greater_than(value)
201
- - filter_less_than(value)
202
- - filter_greater_than_or_equal_to(value)
203
- - filter_less_than_or_equal_to(value)
204
- - filter_is_empty
205
- - filter_is_not_empty
206
- - CheckboxProperty
207
- - filter_equals(value)
208
- - filter_does_not_equal(value)
209
- - SelectProperty
210
- - filter_equals(value)
211
- - filter_does_not_equal(value)
212
- - filter_is_empty
213
- - filter_is_not_empty
214
- - MultiSelectProperty, PeopleProperty, CreatedByProperty, LastEditedByProperty
215
- - filter_contains(value)
216
- - filter_does_not_contain(value)
217
- - filter_is_empty
218
- - filter_is_not_empty
219
- - DateProperty, CreatedTimeProperty, LastEditedTimeProperty
220
- - filter_equals(value(Date / Time / DateTime / String))
221
- - filter_does_not_equal(value(Date / Time / DateTime / String))
222
- - filter_before(value(Date / Time / DateTime / String))
223
- - filter_after(value(Date / Time / DateTime / String))
224
- - filter_on_or_before(value(Date / Time / DateTime / String))
225
- - filter_on_or_after(value(Date / Time / DateTime / String))
226
- - filter_past_week
227
- - filter_past_month
228
- - filter_past_year
229
- - filter_next_week
230
- - filter_next_month
231
- - filter_next_year
232
- - FilesProperty
233
- - filter_is_empty
234
- - filter_is_not_empty
235
- - FormulaProperty
236
- - filter_equals(value(Date / Time / DateTime / String))
237
- - filter_does_not_equal(value(Date / Time / DateTime / String))
238
- - filter_before(value(Date / Time / DateTime / String))
239
- - filter_after(value(Date / Time / DateTime / String))
240
- - filter_on_or_before(value(Date / Time / DateTime / String))
241
- - filter_on_or_after(value(Date / Time / DateTime / String))
242
- - filter_past_week
243
- - filter_past_month
244
- - filter_past_year
245
- - filter_next_week
246
- - filter_next_month
247
- - filter_next_year
248
- - filter_contains(value)
249
- - filter_does_not_contain(value)
250
- - filter_starts_with(value)
251
- - filter_ends_with(value)
252
- - filter_greater_than(value)
253
- - filter_less_than(value)
254
- - filter_greater_than_or_equal_to(value)
255
- - filter_less_than_or_equal_to(value)
256
- - filter_is_empty
257
- - filter_is_not_empty
274
+ ```Ruby
275
+ # query_database method calls Notion API
276
+ db.query_database # retrieves all pages (no filter, no sort)
277
+ db.query_database query # retrieves using query
278
+ ```
279
+
280
+ The query object can be generated from the Property objects included in the database object.
281
+ The Property object can be obtained from the retrieved or assigned database object like as the Page object.
282
+
283
+ `filter_xxxx` methods of the property objects generates a query object.
284
+ These methods are explained in the section of each property object class.
285
+
286
+ ```Ruby
287
+ tp = db.properties["Title"]
288
+ query = tp.filter_starts_with("A").ascending(tp)
289
+ pages = db.query_database query
290
+ ```
258
291
 
259
- #### 3.5.4 Complex conditions
260
- Complex filters can be generated `and` / `or` methods.
292
+ ##### 4.2.2.1 Complex conditions
293
+
294
+ Complex filters can be generated `and` / `or` methods of the Query object.
261
295
  Here are some sample scripts and the json parameters created from them.
262
296
 
263
297
  ```Ruby
264
298
  # Prepare some sample properties
265
- tp = TitleProperty.new "tp"
266
- np = NumberProperty.new "np"
267
- cp = CheckboxProperty.new "cp"
268
- letp = LastEditedTimeProperty.new "letp"
299
+ db = Database.new id: "sample database id",
300
+ assign: [
301
+ TitleProperty, "tp",
302
+ NumberProperty, "np",
303
+ CheckboxProperty, "cp",
304
+ LastEditedTimeProperty, "letp",
305
+ ]
306
+ properties = db.properties # PropertyCache object
307
+ # PropertyCache object can receive [] or values_at methods.
308
+ # `values_at` method is useful when retrieving multiple properties at once.
309
+ (tp, np, cp, letp) = properties.values_at "tp", "np", "cp", "letp"
269
310
  ```
270
311
 
271
312
  - query1: (A and B) filter
313
+
272
314
  ```Ruby
273
315
  query1 = tp.filter_starts_with("start")
274
316
  .and(np.filter_greater_than(100))
@@ -289,6 +331,7 @@ query1 = tp.filter_starts_with("start")
289
331
  ```
290
332
 
291
333
  - query2: (A and B and C) filter
334
+
292
335
  ```Ruby
293
336
  query2 = tp.filter_starts_with("start")
294
337
  .and(np.filter_greater_than(100))
@@ -314,6 +357,7 @@ query2 = tp.filter_starts_with("start")
314
357
  ```
315
358
 
316
359
  - query3: (A or B) filter
360
+
317
361
  ```Ruby
318
362
  query3 = tp.filter_starts_with("start")
319
363
  .or(np.filter_greater_than(100))
@@ -334,6 +378,7 @@ query3 = tp.filter_starts_with("start")
334
378
  ```
335
379
 
336
380
  - query4: (A or B or C) filter
381
+
337
382
  ```Ruby
338
383
  query4 = tp.filter_starts_with("start")
339
384
  .or(np.filter_greater_than(100))
@@ -359,6 +404,7 @@ query4 = tp.filter_starts_with("start")
359
404
  ```
360
405
 
361
406
  - query5: ((A and B) or C) filter
407
+
362
408
  ```Ruby
363
409
  query5 = tp.filter_starts_with("start")
364
410
  .and(np.filter_greater_than(100))
@@ -388,6 +434,7 @@ query5 = tp.filter_starts_with("start")
388
434
  ```
389
435
 
390
436
  - query6: ((A or B) and C) filter
437
+
391
438
  ```Ruby
392
439
  query6 = tp.filter_starts_with("start")
393
440
  .or(np.filter_greater_than(100))
@@ -417,6 +464,7 @@ query6 = tp.filter_starts_with("start")
417
464
  ```
418
465
 
419
466
  - query7: ((A and B) or (C and D)) filter
467
+
420
468
  ```Ruby
421
469
  query7 = np.filter_greater_than(100).and(np.filter_less_than(200))
422
470
  .or(np.filter_greater_than(300).and(np.filter_less_than(400)))
@@ -452,11 +500,13 @@ query7 = np.filter_greater_than(100).and(np.filter_less_than(200))
452
500
  }
453
501
  ```
454
502
 
455
- #### 3.5.5 Sort criteria
503
+ ##### 4.2.2.2 Sort criteria
504
+
456
505
  Sort criteria can be appended to an existing query object.
457
506
  If you don't use the previous filters, you can generate by `Query.new`.
458
507
 
459
508
  - sort criteria only
509
+
460
510
  ```Ruby
461
511
  query8 = Query.new.ascending tp
462
512
  query9 = Query.new.ascending letp
@@ -484,6 +534,7 @@ query12 = Query.new.ascending(tp).descending letp
484
534
  ```
485
535
 
486
536
  - filter with sort
537
+
487
538
  ```Ruby
488
539
  query13 = tp.filter_starts_with("A").ascending(tp)
489
540
 
@@ -494,134 +545,195 @@ query13 = tp.filter_starts_with("A").ascending(tp)
494
545
  [{"property" => "tp", "direction" => "ascending"}]
495
546
  ```
496
547
 
497
- ### 3.6 Access the database or page values and properties
548
+ #### 4.2.3 Create child page
498
549
 
499
- Database or Page values can be accessed by [] access with keywords.
550
+ `create_child_page` creates a child page object of the database.
500
551
 
501
552
  ```Ruby
502
- obj["icon"]
553
+ page = db.create_child_page TitleProperty, "Name"
503
554
  ```
504
555
 
505
- Almost values returns a hash or an array object except "properties".
506
- `obj["properties"]` or `obj.properties` returns a PropertyCache object.
507
- The PropertyCache object is created from json information on the first access and is cached to the Page or Database object.
508
- If page or database object is generated by `.new` method, the object don't have json information.
509
- In this case, the `.properties` method calls `reload` method automatically, then it creates the PropertyCache object from the loaded json information (called auto-load function).
556
+ #### 4.2.4 Update database
510
557
 
511
- ```Ruby
512
- obj["properties"]
513
- # or
514
- obj.properties
515
- ```
558
+ === under construction ===
516
559
 
517
- Each Property object is obtained by [] access with the property name.
518
- The Property object is also created on the first access and is cached to the PropertyCache object.
560
+ ### 4.3 List class
561
+
562
+ `db.query_database` and other API list results returns a List object.
563
+ The list object is an Enumerable object, so usually combines with `.each` method.
519
564
 
520
565
  ```Ruby
521
- np = obj.properties["NumberTitle"]
566
+ db.query_database(query).each do |page|
567
+ # exec some methods for a page object
568
+ end
522
569
  ```
523
570
 
524
- ## 3.7 Set icon (Database / Page)
571
+ Notion API returns only the first page-size objects.
572
+ The default page-size of this library is 100.
573
+ Since the above `.each` method is supported for paging, it will automatically execute API call that obtain the following 100 objects when you used the first 100 objects.
574
+ Users do not have to worry about paging.
525
575
 
526
- Database or Page icon can update by `obj.set_icon` method.
527
- You can set icon as emoji or external url.
576
+ ### 4.4 Block class
528
577
 
529
- ```Ruby
530
- obj.set_icon emoji: "💿" # set emoji
531
- obj.set_icon url: "https://cdn.profile-image.st-hatena.com/users/hkob/profile.png" # set external url
532
- ```
578
+ === under construction ===
533
579
 
534
- ## 3.8 Update page property values
580
+ ### 4.5 Property classes
535
581
 
536
- Page properties can update in the following three ways.
582
+ #### 4.5.1 How to obtain Property object
537
583
 
538
- ### 3.8.1 Assign property and update it (fastest: one API call only)
584
+ There are the following 17 XXXProperty classes corresponding to Notion databases.
539
585
 
540
- This is the fastest way using an empty Page object.
541
- `page.assign_property` generates an empty PropertyCache and an empty XXXProperty.
542
- After updating the property value, please call `page.update`.
543
- Notion API will be called using a JSON payload generated from the PropertyCache object.
586
+ 1. TitleProperty
587
+ 2. RichTextProperty
588
+ 3. UrlProperty
589
+ 4. EmailProperty
590
+ 5. PhoneNumberProperty
591
+ 6. NumberProperty
592
+ 7. CheckboxProperty
593
+ 8. SelectProperty
594
+ 9. MultiSelectProperty
595
+ 10. PeopleProperty
596
+ 11. CreatedByProperty
597
+ 12. LastEditedByProperty
598
+ 13. DateProperty
599
+ 14. CreatedTimeProperty
600
+ 15. LastEditedTimeProperty
601
+ 16. FilesProperty
602
+ 17. FormulaProperty
603
+
604
+ They are child classes of a `Property` class and generated from Page or Database objects.
544
605
 
545
606
  ```Ruby
546
- page = Page.new id: page_id
547
- property = page.assign_property NumberProperty, "NumberTitle"
548
- property.number = 2022
549
- page.update # update page API call
550
- print page
551
- ```
607
+ page = Page.new page_id, assign: [XXXProperty, "property_name"]
608
+ # or
609
+ page = Page.find page_id
552
610
 
553
- ### 3.8.2 Update the loaded page (easy but slow: two API calls)
611
+ xp = page.properties["property_name"]
612
+ # or
613
+ xp, yp = page.properties.values_at "xp_name", "yp_name"
614
+ ```
554
615
 
555
- This is an easiest way using a loaded Page object.
556
- A PropertyCache object is automatically generated by `page.properties`.
557
- After updating the property value, please call `page.update`.
558
- Notion API will be called using a JSON payload generated from the PropertyCache object.
559
- There are two API calls (find and update).
616
+ #### 4.5.2 Query object generator of property objects
560
617
 
561
- ```Ruby
562
- page = Page.find first_page_id # retrieve page API call
563
- property = page.properties["NumberTitle"]
564
- property.number = 2022
565
- page.update # update page API call
566
- print page
567
- ```
618
+ The following methods for the Property objects generate a query object.
568
619
 
569
- ### 3.8.3 Update the unloaded page with auto-load (easy but slow: two API calls)
620
+ - TitleProperty, RichTextProperty, UrlProperty, EmailProperty, PhoneNumberProperty
621
+ - filter_equals(value)
622
+ - filter_does_not_equal(value)
623
+ - filter_contains(value)
624
+ - filter_does_not_contain(value)
625
+ - filter_starts_with(value)
626
+ - filter_ends_with(value)
627
+ - filter_is_empty
628
+ - filter_is_not_empty
629
+ - NumberProperty
630
+ - filter_equals(value)
631
+ - filter_does_not_equal(value)
632
+ - filter_greater_than(value)
633
+ - filter_less_than(value)
634
+ - filter_greater_than_or_equal_to(value)
635
+ - filter_less_than_or_equal_to(value)
636
+ - filter_is_empty
637
+ - filter_is_not_empty
638
+ - CheckboxProperty
639
+ - filter_equals(value)
640
+ - filter_does_not_equal(value)
641
+ - SelectProperty
642
+ - filter_equals(value)
643
+ - filter_does_not_equal(value)
644
+ - filter_is_empty
645
+ - filter_is_not_empty
646
+ - MultiSelectProperty, PeopleProperty, CreatedByProperty, LastEditedByProperty
647
+ - filter_contains(value)
648
+ - filter_does_not_contain(value)
649
+ - filter_is_empty
650
+ - filter_is_not_empty
651
+ - DateProperty, CreatedTimeProperty, LastEditedTimeProperty
652
+ - filter_equals(value(Date / Time / DateTime / String))
653
+ - filter_does_not_equal(value(Date / Time / DateTime / String))
654
+ - filter_before(value(Date / Time / DateTime / String))
655
+ - filter_after(value(Date / Time / DateTime / String))
656
+ - filter_on_or_before(value(Date / Time / DateTime / String))
657
+ - filter_on_or_after(value(Date / Time / DateTime / String))
658
+ - filter_past_week
659
+ - filter_past_month
660
+ - filter_past_year
661
+ - filter_next_week
662
+ - filter_next_month
663
+ - filter_next_year
664
+ - FilesProperty
665
+ - filter_is_empty
666
+ - filter_is_not_empty
667
+ - FormulaProperty
668
+ - filter_equals(value(Date / Time / DateTime / String))
669
+ - filter_does_not_equal(value(Date / Time / DateTime / String))
670
+ - filter_before(value(Date / Time / DateTime / String))
671
+ - filter_after(value(Date / Time / DateTime / String))
672
+ - filter_on_or_before(value(Date / Time / DateTime / String))
673
+ - filter_on_or_after(value(Date / Time / DateTime / String))
674
+ - filter_past_week
675
+ - filter_past_month
676
+ - filter_past_year
677
+ - filter_next_week
678
+ - filter_next_month
679
+ - filter_next_year
680
+ - filter_contains(value)
681
+ - filter_does_not_contain(value)
682
+ - filter_starts_with(value)
683
+ - filter_ends_with(value)
684
+ - filter_greater_than(value)
685
+ - filter_less_than(value)
686
+ - filter_greater_than_or_equal_to(value)
687
+ - filter_less_than_or_equal_to(value)
688
+ - filter_is_empty
689
+ - filter_is_not_empty
570
690
 
571
- This is also an easiest way using an auto-load function of the Page object.
572
- A PropertyCache object is automatically generated by `page.properties` using the auto-load function of page objects.
573
- After updating the property value, please call `page.update`.
574
- Notion API will be called using a JSON payload generated from the PropertyCache object.
575
- There are also two API calls (find and update).
691
+ #### 4.5.3 create or update values for Page properties
576
692
 
577
- ```Ruby
578
- page = Page.new id: first_page_id
579
- property = page.properties["NumberTitle"] # retrieve page API call (auto-load)
580
- property.number = 12345
581
- page.update # update page API call
582
- print page
583
- ```
693
+ Retrieving Page object has XXXProperties with values.
694
+ On the other hand, Assigned Page object has also XXXProperties, but they don't have any information for pages.
584
695
 
585
- ### 3.8.4 Explanation of how to update each property
696
+ XXXProperties can change property values by setter methods.
697
+ Since the setter method is different for each class, it will be explained separately.
586
698
 
587
- #### 3.8.4.1 NumberProperty
699
+ ##### 4.5.3.1 NumberProperty
588
700
 
589
701
  NumberProperty can set a number by `.number=`.
590
702
 
591
703
  ```Ruby
592
704
  np = page.properties["NumberTitle"]
593
- np.number = 456
594
- p np.create_json
595
- # Result => {"number" => 456}
705
+ np.number = 3.14
706
+ p np.property_values_json
707
+ # Result => => {"np"=>{"number"=>3.14, "type"=>"number"}}
596
708
  ```
597
709
 
598
- #### 3.8.4.2 SelectProperty
710
+ ##### 4.5.3.2 SelectProperty
599
711
 
600
712
  NumberProperty can set a select name by `.select=`.
601
713
 
602
714
  ```Ruby
603
715
  sp = page.properties["SelectTitle"]
604
716
  sp.select = "Select 2"
605
- p sp.create_json
606
- # Result => {"select" => {"name" => "Select 2"}}
717
+ p sp.property_values_json
718
+ # Result => {"sp"=>{"type"=>"select", "select"=>{"name"=>"Select 2"}}}
607
719
  ```
608
720
 
609
- #### 3.8.4.3 MultiSelectProperty
721
+ ##### 4.5.3.3 MultiSelectProperty
610
722
 
611
723
  MultiSelectProperty can set a select value or Array of select values by `.multi_select=`.
612
724
 
613
725
  ```Ruby
614
726
  msp = page.properties["MultiSelectTitle"]
615
- msp.select = "MS2"
616
- p msp.create_json
617
- # Result => {"multi_select" => [{"name" => "MS2"}]}
727
+ msp.multi_select = "MS2"
728
+ p msp.property_values_json
729
+ # Result => {"msp"=>{"type"=>"multi_select", "multi_select"=>[{"name"=>"MS2"}]}}
618
730
 
619
731
  msp.multi_select = %w[MS2 MS1]
620
- p msp.create_json
621
- # Result => {"multi_select" => [{"name" => "MS2"}, {"name" => "MS1"}]}
732
+ p msp.property_values_json
733
+ # Result => {"msp"=>{"type"=>"multi_select", "multi_select"=>[{"name"=>"MS2"}, {"name"=>"MS1"}]}}
622
734
  ```
623
735
 
624
- #### 3.8.4.4 DateProperty
736
+ ##### 4.5.3.4 DateProperty
625
737
 
626
738
  DateProperty can set a start_date or end_date by `.start_date=` or `end_date=`.
627
739
  Date, Time, DateTime or String object can be used to the argument.
@@ -629,48 +741,183 @@ Date, Time, DateTime or String object can be used to the argument.
629
741
  ```Ruby
630
742
  dp = page.properties["DateTitle"]
631
743
  dp.start_date = Date.new(2022, 2, 22)
632
- p dp.create_json
633
- # Result => {"start" => "2022-02-22"}
744
+ p dp.property_values_json
745
+ # Result => {"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-22", "end"=>nil, "time_zone"=>nil}}}
634
746
 
635
747
  dp.start_date = Time.new(2022, 2, 22, 1, 23, 45, "+09:00")
636
- p dp.create_json
637
- # Result => {"start" => "2022-02-22T01:23:45+09:00"}
748
+ p dp.property_values_json
749
+ # Result =>{"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-22T01:23:45+09:00", "end"=>nil, "time_zone"=>nil}}}
638
750
 
639
751
  dp.start_date = DateTime.new(2022, 2, 23, 1, 23, 45, "+09:00")
640
- p dp.create_json
641
- # Result => {"start" => "2022-02-23T01:23:45+09:00"}
752
+ p dp.property_values_json
753
+ # Result => {"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-23T01:23:45+09:00", "end"=>nil, "time_zone"=>nil}}}
642
754
 
643
755
  dp.start_date = Date.new(2022, 2, 20)
644
756
  dp.end_date = Date.new(2022, 2, 22)
645
- p dp.create_json
646
- # Result => {"start" => "2022-02-20", "end" => "2022-02-22"}
757
+ p dp.property_values_json
758
+ # Result => => {"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-20", "end"=>"2022-02-22", "time_zone"=>nil}}}
647
759
 
648
760
  dp.start_date = Time.new(2022, 2, 21, 1, 23, 45, "+09:00")
649
761
  dp.end_date = Time.new(2022, 2, 22, 1, 23, 45, "+09:00")
650
- p dp.create_json
762
+ p dp.property_values_json
651
763
  # Result => {"start" => "2022-02-21T01:23:45+09:00", "end" => "2022-02-22T01:23:45+09:00"}
652
764
 
653
765
  dp.start_date = DateTime.new(2022, 2, 21, 1, 23, 45, "+09:00")
654
766
  dp.end_date = DateTime.new(2022, 2, 22, 1, 23, 45, "+09:00")
655
- p dp.create_json
656
- # result => {"start" => "2022-02-21T01:23:45+09:00", "end" => "2022-02-22T01:23:45+09:00"}
767
+ p dp.property_values_json
768
+ # result => {"dp"=>{"type"=>"date", "date"=>{"start"=>"2022-02-21T01:23:45+09:00", "end"=>nil, "time_zone"=>nil}}}
657
769
  ```
658
770
 
659
- ### 3.9 Iteration of list object
771
+ ##### 4.5.3.4 UrlProperty
660
772
 
661
- Some methods like as `Database.query` return a list object.
662
- Since the list object also has a json array object, `Enumerable` module is implemented.
663
- Each iteration creates a Page or Block object and calls the block with it as an argument.
773
+ UrlProperty can set a url by `.url=`.
664
774
 
665
775
  ```Ruby
666
- pages = Database.query("c37a2c66-e3aa-4a0d-a447-73de3b80c253") # retrieves all pages
667
- pages.each do |page| # obj's class is Page or Block
668
- page.set_icon(emoji: "💿") unless page["icon"]
669
- end
776
+ up = page.properties["UrlTitle"]
777
+ up.url = "https://www.google.com/"
778
+ p up.property_values_json
779
+ # result => {"up"=>{"url"=>"https://www.google.com/", "type"=>"url"}}
780
+ ```
781
+
782
+ ##### 4.5.3.5 EmailProperty
783
+
784
+ EmailProperty can set an email by `.email=`.
785
+
786
+ ```Ruby
787
+ ep = page.properties["MailTitle"]
788
+ ep.email = "https://www.google.com/"
789
+ p ep.property_values_json
790
+ # result => {"ep"=>{"email"=>"hkobhkob@gmail.com", "type"=>"email"}}
670
791
  ```
671
792
 
672
- ## 4. ChangeLog
793
+ ##### 4.5.3.6 PhoneNumberProperty
794
+
795
+ PhoneNumberProperty can set an phone number by `.phone_number=`.
796
+
797
+ ```Ruby
798
+ pp = page.properties["TelTitle"]
799
+ pp.phone_number = "xx-xxxx-xxxx"
800
+ p pp.property_values_json
801
+ # result => {"pp"=>{"phone_number"=>"xx-xxxx-xxxx", "type"=>"phone_number"}}
802
+ ```
803
+
804
+ ##### 4.5.3.7 PeopleProperty
805
+
806
+ PeopleProperty can set an people by `.people=`.
807
+ PeopleProperty can set a user_id/UserObject value or Array of user_id/UserObject values by `.people=`.
808
+
809
+ ```Ruby
810
+ pp = page.properties["UserTitle"]
811
+ pp.people = "user_id1"
812
+ p pp.property_values_json
813
+ # result => {"pp"=>{"type"=>"people", "people"=>[{"object"=>"user", "id"=>"user_id1"}]}}
814
+
815
+ pp.people = UserObject.new json: user1_json
816
+ p pp.property_values_json
817
+ # result => {"pp"=>{"type"=>"people", "people"=>[{"object"=>"user", "id"=>"user_id1_from_json"}]}}
818
+ ```
819
+
820
+ ```Ruby
821
+ pp.people = %w[user_id2 user_id3]
822
+ p pp.property_values_json
823
+ # result => {"pp"=>{"type"=>"people", "people"=>[{"object"=>"user", "id"=>"user_id2"}, {"object"=>"user", "id"=>"user_id3"}]}}
824
+
825
+ u2 = UserObject.new(json: user2_json)
826
+ u3 = UserObject.new(json: user3_json)
827
+ pp.people = [u2, u3]
828
+ p pp.property_values_json
829
+ # result => {"pp"=>{"type"=>"people", "people"=>[{"object"=>"user", "id"=>"user_id2_from_json"}, {"object"=>"user", "id"=>"user_id3_from_json"}]}}
830
+ ```
831
+
832
+ ##### 4.5.3.8 TitleProperty, RichTextProperty
833
+
834
+ TextProperty's subclasses (TitleProperty, RichTextProperty) have an array of TextObject objects.
835
+ `[]` method returns an existing TextObject.
836
+ The obtained TextObject can be set text by `.text=`.
837
+
838
+ ```Ruby
839
+ pp = page.properties["Title"]
840
+ tp[0].text = "ABC\n"
841
+ p tp.property_values_json
842
+ # result => {"tp"=>{"type"=>"title", "title"=>[{"type"=>"text", "text"=>{"content"=>"ABC\n", "link"=>nil}, "plain_text"=>"ABC\n", "href"=>nil}]}}
843
+ ```
844
+
845
+ `<<` method appends a new TextObject or a String.
846
+ ```Ruby
847
+ to = TextObject.new "DEF"
848
+ to.bold = true
849
+ to.italic = true
850
+ to.strikethrough = true
851
+ to.underline = true
852
+ to.code = true
853
+ to.color = "default"
854
+ tp << to
855
+ p tp.property_values_json
856
+ # result => {"tp"=>{"type"=>"title","title"=>[{"type"=>"text","text"=>{"content"=>"ABC\n","link"=>nil},"plain_text"=>"ABC\n","href"=>nil},{"type"=>"text","text"=>{"content"=>"DEF","link"=>nil},"plain_text"=>"DEF","href"=>nil,"annotations"=>{"bold"=>true,"italic"=>true,"strikethrough"=>true,"underline"=>true,"code"=>true,"color"=>"default"}}]}}
857
+ ```
858
+
859
+ `delete_at(index)` method remove a TextObject at index.
860
+ ```Ruby
861
+ tp.delete_at 1
862
+ tp << "GHI"
863
+ p tp.property_values_json
864
+ # result => {"tp"=>{"type"=>"title", "title"=>[{"type"=>"text", "text"=>{"content"=>"ABC\n", "link"=>nil}, "plain_text"=>"ABC\n", "href"=>nil}, {"type"=>"text", "text"=>{"content"=>"DEF", "link"=>nil}, "plain_text"=>"DEF", "href"=>nil, "annotations"=>{"bold"=>true, "italic"=>true, "strikethrough"=>true, "underline"=>true, "code"=>true, "color"=>"default"}}, {"type"=>"text", "text"=>{"content"=>"GHI", "link"=>nil}, "plain_text"=>"GHI", "href"=>nil}]}}
865
+ ```
866
+
867
+ ##### 4.5.3.9 CheckboxProperty
868
+
869
+ PeopleProperty can set a boolean value by `.checkbox=`.
870
+ ```Ruby
871
+ cp = page.properties["CheckboxTitle"]
872
+ cp.checkbox = true
873
+ p cp.property_values_json
874
+ # result => {"cp"=>{"checkbox"=>true, "type"=>"checkbox"}}
875
+ ```
876
+
877
+ ##### 4.5.3.10 EmailProperty
878
+
879
+ EmailProperty can set an email address by `.email=`.
880
+ ```Ruby
881
+ ep = page.properties["MailTitle"]
882
+ ep.email = "hkobhkob@gmail.com"
883
+ p ep.property_values_json
884
+ # result => {"ep"=>{"email"=>"hkobhkob@gmail.com", "type"=>"email"}}
885
+ ```
886
+
887
+ ##### 4.5.3.11 FilesProperty
888
+
889
+ FilesProperty can set an external url or Array of external urls by `.files=`.
890
+
891
+ ```Ruby
892
+ fp = page.properties["FilesTitle"]
893
+ fp.files = "F1"
894
+ p fp.property_values_json
895
+ # Result => {"fp"=>{"files"=>[{"name"=>"F1", "type"=>"external", "external"=>{"url"=>"F1"}}], "type"=>"files"}}
896
+
897
+ fp.files = %w[F2 F3]
898
+ p fp.property_values_json
899
+ # Result => {"fp"=>{"files"=>[{"name"=>"F2", "type"=>"external", "external"=>{"url"=>"F2"}}, {"name"=>"F3", "type"=>"external", "external"=>{"url"=>"F3"}}], "type"=>"files"}}
900
+ ```
901
+
902
+ ##### 4.5.3.12 RelationProperty
903
+
904
+ RelationProperty can set an relation's page_id or Array of relation's page_ids by `.relation=`.
905
+
906
+ ```Ruby
907
+ rp = page.properties["RelationTitle"]
908
+ rp.relation = "R1"
909
+ p rp.property_values_json
910
+ # Result => {"rp"=>{"type"=>"relation", "relation"=>[{"id"=>"R1"}]}}
911
+
912
+ rp.relation = %w[R2 R3]
913
+ p rp.property_values_json
914
+ # Result => {"rp"=>{"type"=>"relation", "relation"=>[{"id"=>"R2"}, {"id"=>"R3"}]}}
915
+ ```
916
+
917
+
918
+ ## 6. ChangeLog
673
919
 
920
+ - 2022/3/14 Exclude notion-ruby-client, update Property values, update for Notion-Version 2022-02-22
674
921
  - 2022/2/25 add_property_for_update -> assign_property, update README.md
675
922
  - 2022/2/20 add support for MultiSelectProperty
676
923
  - 2022/2/19 add support for SelectProperty
@@ -681,18 +928,18 @@ end
681
928
  - 2022/2/13 added Page#set_icon
682
929
  - 2022/2/13 First commit
683
930
 
684
- ## 5. Contributing
931
+ ## 6. Contributing
685
932
 
686
- Bug reports and pull requests are welcome on GitHub at https://github.com/hkob/notion_ruby_mapping. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/notion_ruby_mapping/blob/main/CODE_OF_CONDUCT.md).
933
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/hkob/notion_ruby_mapping>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/notion_ruby_mapping/blob/main/CODE_OF_CONDUCT.md).
687
934
 
688
- ## 6. License
935
+ ## 7. License
689
936
 
690
937
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
691
938
 
692
- ## 7. Code of Conduct
939
+ ## 8. Code of Conduct
693
940
 
694
941
  Everyone interacting in the NotionRubyMapping project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/notion_ruby_mapping/blob/main/CODE_OF_CONDUCT.md).
695
942
 
696
- ## 8. Acknowledgements
943
+ ## 9. Acknowledgements
697
944
 
698
945
  The code depends on [notion-ruby-client](https://github.com/orbit-love/notion-ruby-client).