jpie 0.4.5 → 1.0.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/.gitignore +21 -0
- data/.rspec +3 -0
- data/.rubocop.yml +35 -110
- data/.travis.yml +7 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +312 -0
- data/README.md +2072 -140
- data/Rakefile +3 -14
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/jpie.gemspec +18 -35
- data/kiln/app/resources/user_message_resource.rb +2 -0
- data/lib/jpie.rb +3 -24
- data/lib/json_api/active_storage/deserialization.rb +106 -0
- data/lib/json_api/active_storage/detection.rb +74 -0
- data/lib/json_api/active_storage/serialization.rb +32 -0
- data/lib/json_api/configuration.rb +58 -0
- data/lib/json_api/controllers/base_controller.rb +26 -0
- data/lib/json_api/controllers/concerns/controller_helpers.rb +223 -0
- data/lib/json_api/controllers/concerns/resource_actions.rb +657 -0
- data/lib/json_api/controllers/relationships_controller.rb +504 -0
- data/lib/json_api/controllers/resources_controller.rb +6 -0
- data/lib/json_api/errors/parameter_not_allowed.rb +19 -0
- data/lib/json_api/railtie.rb +75 -0
- data/lib/json_api/resources/active_storage_blob_resource.rb +11 -0
- data/lib/json_api/resources/resource.rb +238 -0
- data/lib/json_api/resources/resource_loader.rb +35 -0
- data/lib/json_api/routing.rb +72 -0
- data/lib/json_api/serialization/deserializer.rb +362 -0
- data/lib/json_api/serialization/serializer.rb +320 -0
- data/lib/json_api/support/active_storage_support.rb +85 -0
- data/lib/json_api/support/collection_query.rb +406 -0
- data/lib/json_api/support/instrumentation.rb +42 -0
- data/lib/json_api/support/param_helpers.rb +51 -0
- data/lib/json_api/support/relationship_guard.rb +16 -0
- data/lib/json_api/support/relationship_helpers.rb +74 -0
- data/lib/json_api/support/resource_identifier.rb +87 -0
- data/lib/json_api/support/responders.rb +100 -0
- data/lib/json_api/support/response_helpers.rb +10 -0
- data/lib/json_api/support/sort_parsing.rb +21 -0
- data/lib/json_api/support/type_conversion.rb +21 -0
- data/lib/json_api/testing/test_helper.rb +76 -0
- data/lib/json_api/testing.rb +3 -0
- data/lib/{jpie → json_api}/version.rb +2 -2
- data/lib/json_api.rb +50 -0
- data/lib/rubocop/cop/custom/hash_value_omission.rb +53 -0
- metadata +50 -169
- data/.cursor/rules/dependencies.mdc +0 -19
- data/.cursor/rules/examples.mdc +0 -16
- data/.cursor/rules/git.mdc +0 -14
- data/.cursor/rules/project_structure.mdc +0 -30
- data/.cursor/rules/publish_gem.mdc +0 -73
- data/.cursor/rules/security.mdc +0 -14
- data/.cursor/rules/style.mdc +0 -15
- data/.cursor/rules/testing.mdc +0 -16
- data/.overcommit.yml +0 -35
- data/CHANGELOG.md +0 -164
- data/LICENSE.txt +0 -21
- data/PUBLISHING.md +0 -111
- data/examples/basic_example.md +0 -146
- data/examples/including_related_resources.md +0 -491
- data/examples/pagination.md +0 -303
- data/examples/relationships.md +0 -114
- data/examples/resource_attribute_configuration.md +0 -147
- data/examples/resource_meta_configuration.md +0 -244
- data/examples/rspec_testing.md +0 -130
- data/examples/single_table_inheritance.md +0 -160
- data/lib/jpie/configuration.rb +0 -12
- data/lib/jpie/controller/crud_actions.rb +0 -141
- data/lib/jpie/controller/error_handling/handler_setup.rb +0 -124
- data/lib/jpie/controller/error_handling/handlers.rb +0 -109
- data/lib/jpie/controller/error_handling.rb +0 -23
- data/lib/jpie/controller/json_api_validation.rb +0 -193
- data/lib/jpie/controller/parameter_parsing.rb +0 -78
- data/lib/jpie/controller/related_actions.rb +0 -45
- data/lib/jpie/controller/relationship_actions.rb +0 -291
- data/lib/jpie/controller/relationship_validation.rb +0 -117
- data/lib/jpie/controller/rendering.rb +0 -154
- data/lib/jpie/controller.rb +0 -45
- data/lib/jpie/deserializer.rb +0 -110
- data/lib/jpie/errors.rb +0 -117
- data/lib/jpie/generators/resource_generator.rb +0 -116
- data/lib/jpie/generators/templates/resource.rb.erb +0 -31
- data/lib/jpie/railtie.rb +0 -42
- data/lib/jpie/resource/attributable.rb +0 -112
- data/lib/jpie/resource/inferrable.rb +0 -43
- data/lib/jpie/resource/sortable.rb +0 -93
- data/lib/jpie/resource.rb +0 -147
- data/lib/jpie/routing.rb +0 -59
- data/lib/jpie/serializer.rb +0 -205
data/examples/pagination.md
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
# Pagination Example
|
|
2
|
-
|
|
3
|
-
This example demonstrates how to implement pagination with JPie resources using both simple and JSON:API standard pagination parameters.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
### 1. Model (`app/models/article.rb`)
|
|
8
|
-
```ruby
|
|
9
|
-
class Article < ActiveRecord::Base
|
|
10
|
-
validates :title, presence: true
|
|
11
|
-
validates :content, presence: true
|
|
12
|
-
end
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### 2. Resource (`app/resources/article_resource.rb`)
|
|
16
|
-
```ruby
|
|
17
|
-
class ArticleResource < JPie::Resource
|
|
18
|
-
attributes :title, :content, :published_at
|
|
19
|
-
end
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### 3. Controller (`app/controllers/articles_controller.rb`)
|
|
23
|
-
```ruby
|
|
24
|
-
class ArticlesController < ApplicationController
|
|
25
|
-
include JPie::Controller
|
|
26
|
-
end
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### 4. Routes (`config/routes.rb`)
|
|
30
|
-
```ruby
|
|
31
|
-
Rails.application.routes.draw do
|
|
32
|
-
resources :articles
|
|
33
|
-
end
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## HTTP Examples
|
|
37
|
-
|
|
38
|
-
### Simple Pagination Parameters
|
|
39
|
-
|
|
40
|
-
#### Get First Page with 5 Articles
|
|
41
|
-
```http
|
|
42
|
-
GET /articles?page=1&per_page=5
|
|
43
|
-
Accept: application/vnd.api+json
|
|
44
|
-
|
|
45
|
-
HTTP/1.1 200 OK
|
|
46
|
-
Content-Type: application/vnd.api+json
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
"data": [
|
|
50
|
-
{
|
|
51
|
-
"id": "1",
|
|
52
|
-
"type": "articles",
|
|
53
|
-
"attributes": {
|
|
54
|
-
"title": "First Article",
|
|
55
|
-
"content": "Content of first article",
|
|
56
|
-
"published_at": "2024-01-01T10:00:00Z"
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"id": "2",
|
|
61
|
-
"type": "articles",
|
|
62
|
-
"attributes": {
|
|
63
|
-
"title": "Second Article",
|
|
64
|
-
"content": "Content of second article",
|
|
65
|
-
"published_at": "2024-01-02T10:00:00Z"
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
],
|
|
69
|
-
"meta": {
|
|
70
|
-
"pagination": {
|
|
71
|
-
"page": 1,
|
|
72
|
-
"per_page": 5,
|
|
73
|
-
"total_pages": 4,
|
|
74
|
-
"total_count": 20
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
"links": {
|
|
78
|
-
"self": "http://example.com/articles?page=1&per_page=5",
|
|
79
|
-
"first": "http://example.com/articles?page=1&per_page=5",
|
|
80
|
-
"last": "http://example.com/articles?page=4&per_page=5",
|
|
81
|
-
"next": "http://example.com/articles?page=2&per_page=5"
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
#### Get Second Page
|
|
87
|
-
```http
|
|
88
|
-
GET /articles?page=2&per_page=5
|
|
89
|
-
Accept: application/vnd.api+json
|
|
90
|
-
|
|
91
|
-
HTTP/1.1 200 OK
|
|
92
|
-
Content-Type: application/vnd.api+json
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
"data": [
|
|
96
|
-
{
|
|
97
|
-
"id": "6",
|
|
98
|
-
"type": "articles",
|
|
99
|
-
"attributes": {
|
|
100
|
-
"title": "Sixth Article",
|
|
101
|
-
"content": "Content of sixth article",
|
|
102
|
-
"published_at": "2024-01-06T10:00:00Z"
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
],
|
|
106
|
-
"meta": {
|
|
107
|
-
"pagination": {
|
|
108
|
-
"page": 2,
|
|
109
|
-
"per_page": 5,
|
|
110
|
-
"total_pages": 4,
|
|
111
|
-
"total_count": 20
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
"links": {
|
|
115
|
-
"self": "http://example.com/articles?page=2&per_page=5",
|
|
116
|
-
"first": "http://example.com/articles?page=1&per_page=5",
|
|
117
|
-
"last": "http://example.com/articles?page=4&per_page=5",
|
|
118
|
-
"prev": "http://example.com/articles?page=1&per_page=5",
|
|
119
|
-
"next": "http://example.com/articles?page=3&per_page=5"
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### JSON:API Standard Pagination Parameters
|
|
125
|
-
|
|
126
|
-
#### Get First Page Using JSON:API Format
|
|
127
|
-
```http
|
|
128
|
-
GET /articles?page[number]=1&page[size]=3
|
|
129
|
-
Accept: application/vnd.api+json
|
|
130
|
-
|
|
131
|
-
HTTP/1.1 200 OK
|
|
132
|
-
Content-Type: application/vnd.api+json
|
|
133
|
-
|
|
134
|
-
{
|
|
135
|
-
"data": [
|
|
136
|
-
{
|
|
137
|
-
"id": "1",
|
|
138
|
-
"type": "articles",
|
|
139
|
-
"attributes": {
|
|
140
|
-
"title": "First Article",
|
|
141
|
-
"content": "Content of first article",
|
|
142
|
-
"published_at": "2024-01-01T10:00:00Z"
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
"id": "2",
|
|
147
|
-
"type": "articles",
|
|
148
|
-
"attributes": {
|
|
149
|
-
"title": "Second Article",
|
|
150
|
-
"content": "Content of second article",
|
|
151
|
-
"published_at": "2024-01-02T10:00:00Z"
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
"id": "3",
|
|
156
|
-
"type": "articles",
|
|
157
|
-
"attributes": {
|
|
158
|
-
"title": "Third Article",
|
|
159
|
-
"content": "Content of third article",
|
|
160
|
-
"published_at": "2024-01-03T10:00:00Z"
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
],
|
|
164
|
-
"meta": {
|
|
165
|
-
"pagination": {
|
|
166
|
-
"page": 1,
|
|
167
|
-
"per_page": 3,
|
|
168
|
-
"total_pages": 7,
|
|
169
|
-
"total_count": 20
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
"links": {
|
|
173
|
-
"self": "http://example.com/articles?page=1&per_page=3",
|
|
174
|
-
"first": "http://example.com/articles?page=1&per_page=3",
|
|
175
|
-
"last": "http://example.com/articles?page=7&per_page=3",
|
|
176
|
-
"next": "http://example.com/articles?page=2&per_page=3"
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Pagination with Sorting
|
|
182
|
-
|
|
183
|
-
#### Get Sorted and Paginated Results
|
|
184
|
-
```http
|
|
185
|
-
GET /articles?sort=-published_at&page=1&per_page=3
|
|
186
|
-
Accept: application/vnd.api+json
|
|
187
|
-
|
|
188
|
-
HTTP/1.1 200 OK
|
|
189
|
-
Content-Type: application/vnd.api+json
|
|
190
|
-
|
|
191
|
-
{
|
|
192
|
-
"data": [
|
|
193
|
-
{
|
|
194
|
-
"id": "20",
|
|
195
|
-
"type": "articles",
|
|
196
|
-
"attributes": {
|
|
197
|
-
"title": "Latest Article",
|
|
198
|
-
"content": "Most recent content",
|
|
199
|
-
"published_at": "2024-01-20T10:00:00Z"
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
"id": "19",
|
|
204
|
-
"type": "articles",
|
|
205
|
-
"attributes": {
|
|
206
|
-
"title": "Second Latest Article",
|
|
207
|
-
"content": "Second most recent content",
|
|
208
|
-
"published_at": "2024-01-19T10:00:00Z"
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
"id": "18",
|
|
213
|
-
"type": "articles",
|
|
214
|
-
"attributes": {
|
|
215
|
-
"title": "Third Latest Article",
|
|
216
|
-
"content": "Third most recent content",
|
|
217
|
-
"published_at": "2024-01-18T10:00:00Z"
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
],
|
|
221
|
-
"meta": {
|
|
222
|
-
"pagination": {
|
|
223
|
-
"page": 1,
|
|
224
|
-
"per_page": 3,
|
|
225
|
-
"total_pages": 7,
|
|
226
|
-
"total_count": 20
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
"links": {
|
|
230
|
-
"self": "http://example.com/articles?sort=-published_at&page=1&per_page=3",
|
|
231
|
-
"first": "http://example.com/articles?sort=-published_at&page=1&per_page=3",
|
|
232
|
-
"last": "http://example.com/articles?sort=-published_at&page=7&per_page=3",
|
|
233
|
-
"next": "http://example.com/articles?sort=-published_at&page=2&per_page=3"
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Last Page Response
|
|
239
|
-
|
|
240
|
-
#### Get Last Page
|
|
241
|
-
```http
|
|
242
|
-
GET /articles?page=4&per_page=5
|
|
243
|
-
Accept: application/vnd.api+json
|
|
244
|
-
|
|
245
|
-
HTTP/1.1 200 OK
|
|
246
|
-
Content-Type: application/vnd.api+json
|
|
247
|
-
|
|
248
|
-
{
|
|
249
|
-
"data": [
|
|
250
|
-
{
|
|
251
|
-
"id": "20",
|
|
252
|
-
"type": "articles",
|
|
253
|
-
"attributes": {
|
|
254
|
-
"title": "Last Article",
|
|
255
|
-
"content": "Content of last article",
|
|
256
|
-
"published_at": "2024-01-20T10:00:00Z"
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
],
|
|
260
|
-
"meta": {
|
|
261
|
-
"pagination": {
|
|
262
|
-
"page": 4,
|
|
263
|
-
"per_page": 5,
|
|
264
|
-
"total_pages": 4,
|
|
265
|
-
"total_count": 20
|
|
266
|
-
}
|
|
267
|
-
},
|
|
268
|
-
"links": {
|
|
269
|
-
"self": "http://example.com/articles?page=4&per_page=5",
|
|
270
|
-
"first": "http://example.com/articles?page=1&per_page=5",
|
|
271
|
-
"last": "http://example.com/articles?page=4&per_page=5",
|
|
272
|
-
"prev": "http://example.com/articles?page=3&per_page=5"
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### Empty Results
|
|
278
|
-
|
|
279
|
-
#### Get Page Beyond Available Data
|
|
280
|
-
```http
|
|
281
|
-
GET /articles?page=10&per_page=5
|
|
282
|
-
Accept: application/vnd.api+json
|
|
283
|
-
|
|
284
|
-
HTTP/1.1 200 OK
|
|
285
|
-
Content-Type: application/vnd.api+json
|
|
286
|
-
|
|
287
|
-
{
|
|
288
|
-
"data": [],
|
|
289
|
-
"meta": {
|
|
290
|
-
"pagination": {
|
|
291
|
-
"page": 10,
|
|
292
|
-
"per_page": 5,
|
|
293
|
-
"total_pages": 4,
|
|
294
|
-
"total_count": 20
|
|
295
|
-
}
|
|
296
|
-
},
|
|
297
|
-
"links": {
|
|
298
|
-
"self": "http://example.com/articles?page=10&per_page=5",
|
|
299
|
-
"first": "http://example.com/articles?page=1&per_page=5",
|
|
300
|
-
"last": "http://example.com/articles?page=4&per_page=5"
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
```
|
data/examples/relationships.md
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# JSON:API Relationship Management
|
|
2
|
-
|
|
3
|
-
This example demonstrates how to manage relationships using JPie's JSON:API compliant relationship endpoints.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
Define your resources with relationships:
|
|
8
|
-
|
|
9
|
-
```ruby
|
|
10
|
-
# app/resources/user_resource.rb
|
|
11
|
-
class UserResource < JPie::Resource
|
|
12
|
-
model User
|
|
13
|
-
attributes :name, :email
|
|
14
|
-
has_many :posts
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# app/resources/post_resource.rb
|
|
18
|
-
class PostResource < JPie::Resource
|
|
19
|
-
model Post
|
|
20
|
-
attributes :title, :content
|
|
21
|
-
has_one :author, resource: 'UserResource'
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# app/controllers/users_controller.rb
|
|
25
|
-
class UsersController < ApplicationController
|
|
26
|
-
include JPie::Controller
|
|
27
|
-
end
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Configure routes:
|
|
31
|
-
|
|
32
|
-
```ruby
|
|
33
|
-
# config/routes.rb
|
|
34
|
-
Rails.application.routes.draw do
|
|
35
|
-
jpie_resources :users
|
|
36
|
-
jpie_resources :posts
|
|
37
|
-
end
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Relationship Operations
|
|
41
|
-
|
|
42
|
-
### Get Relationship Linkage
|
|
43
|
-
|
|
44
|
-
```http
|
|
45
|
-
GET /users/1/relationships/posts
|
|
46
|
-
|
|
47
|
-
Response:
|
|
48
|
-
{
|
|
49
|
-
"data": [
|
|
50
|
-
{ "type": "posts", "id": "1" },
|
|
51
|
-
{ "type": "posts", "id": "3" }
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Replace Relationship
|
|
57
|
-
|
|
58
|
-
```http
|
|
59
|
-
PATCH /users/1/relationships/posts
|
|
60
|
-
Content-Type: application/vnd.api+json
|
|
61
|
-
|
|
62
|
-
{
|
|
63
|
-
"data": [
|
|
64
|
-
{ "type": "posts", "id": "2" },
|
|
65
|
-
{ "type": "posts", "id": "4" }
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Add to Relationship
|
|
71
|
-
|
|
72
|
-
```http
|
|
73
|
-
POST /users/1/relationships/posts
|
|
74
|
-
Content-Type: application/vnd.api+json
|
|
75
|
-
|
|
76
|
-
{
|
|
77
|
-
"data": [
|
|
78
|
-
{ "type": "posts", "id": "5" }
|
|
79
|
-
]
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Remove from Relationship
|
|
84
|
-
|
|
85
|
-
```http
|
|
86
|
-
DELETE /users/1/relationships/posts
|
|
87
|
-
Content-Type: application/vnd.api+json
|
|
88
|
-
|
|
89
|
-
{
|
|
90
|
-
"data": [
|
|
91
|
-
{ "type": "posts", "id": "2" }
|
|
92
|
-
]
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Get Related Resources
|
|
97
|
-
|
|
98
|
-
```http
|
|
99
|
-
GET /users/1/posts
|
|
100
|
-
|
|
101
|
-
Response:
|
|
102
|
-
{
|
|
103
|
-
"data": [
|
|
104
|
-
{
|
|
105
|
-
"type": "posts",
|
|
106
|
-
"id": "1",
|
|
107
|
-
"attributes": {
|
|
108
|
-
"title": "First Post",
|
|
109
|
-
"content": "Hello world!"
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
]
|
|
113
|
-
}
|
|
114
|
-
```
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# Resource Attribute Configuration Example
|
|
2
|
-
|
|
3
|
-
This example demonstrates all the different ways to configure resource attributes in JPie, showcasing the various configuration patterns and customization techniques available for attributes.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
### 1. Model (`app/models/user.rb`)
|
|
8
|
-
```ruby
|
|
9
|
-
class User < ActiveRecord::Base
|
|
10
|
-
validates :first_name, presence: true
|
|
11
|
-
validates :last_name, presence: true
|
|
12
|
-
validates :email, presence: true, uniqueness: true
|
|
13
|
-
validates :username, presence: true, uniqueness: true
|
|
14
|
-
|
|
15
|
-
def active?
|
|
16
|
-
true # Simple boolean for demonstration
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### 2. Resource with All Attribute Configuration Types (`app/resources/user_resource.rb`)
|
|
22
|
-
```ruby
|
|
23
|
-
class UserResource < JPie::Resource
|
|
24
|
-
# 1. Basic attributes - direct model attribute access
|
|
25
|
-
attributes :email, :first_name, :last_name
|
|
26
|
-
|
|
27
|
-
# 2. Attribute with custom attr mapping (maps to different model attribute)
|
|
28
|
-
attribute :display_name, attr: :username
|
|
29
|
-
|
|
30
|
-
# 3. Attribute with block override
|
|
31
|
-
attribute :status do
|
|
32
|
-
object.active? ? 'active' : 'inactive'
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# 4. Attribute with custom method override
|
|
36
|
-
attribute :full_name
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
# Custom method for attribute override
|
|
41
|
-
def full_name
|
|
42
|
-
"#{object.first_name} #{object.last_name}".strip
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### 3. Controller (`app/controllers/users_controller.rb`)
|
|
48
|
-
```ruby
|
|
49
|
-
class UsersController < ApplicationController
|
|
50
|
-
include JPie::Controller
|
|
51
|
-
end
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## HTTP Examples
|
|
55
|
-
|
|
56
|
-
### Create User
|
|
57
|
-
```http
|
|
58
|
-
POST /users
|
|
59
|
-
Content-Type: application/vnd.api+json
|
|
60
|
-
|
|
61
|
-
{
|
|
62
|
-
"data": {
|
|
63
|
-
"type": "users",
|
|
64
|
-
"attributes": {
|
|
65
|
-
"email": "john.doe@example.com",
|
|
66
|
-
"first_name": "John",
|
|
67
|
-
"last_name": "Doe"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
HTTP/1.1 201 Created
|
|
73
|
-
Content-Type: application/vnd.api+json
|
|
74
|
-
|
|
75
|
-
{
|
|
76
|
-
"data": {
|
|
77
|
-
"id": "1",
|
|
78
|
-
"type": "users",
|
|
79
|
-
"attributes": {
|
|
80
|
-
"email": "john.doe@example.com",
|
|
81
|
-
"first_name": "John",
|
|
82
|
-
"last_name": "Doe",
|
|
83
|
-
"display_name": "johndoe",
|
|
84
|
-
"status": "active",
|
|
85
|
-
"full_name": "John Doe"
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Update User
|
|
92
|
-
```http
|
|
93
|
-
PATCH /users/1
|
|
94
|
-
Content-Type: application/vnd.api+json
|
|
95
|
-
|
|
96
|
-
{
|
|
97
|
-
"data": {
|
|
98
|
-
"id": "1",
|
|
99
|
-
"type": "users",
|
|
100
|
-
"attributes": {
|
|
101
|
-
"first_name": "Jonathan"
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
HTTP/1.1 200 OK
|
|
107
|
-
Content-Type: application/vnd.api+json
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
"data": {
|
|
111
|
-
"id": "1",
|
|
112
|
-
"type": "users",
|
|
113
|
-
"attributes": {
|
|
114
|
-
"email": "john.doe@example.com",
|
|
115
|
-
"first_name": "Jonathan",
|
|
116
|
-
"last_name": "Doe",
|
|
117
|
-
"display_name": "johndoe",
|
|
118
|
-
"status": "active",
|
|
119
|
-
"full_name": "Jonathan Doe"
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Get User with All Attribute Configuration Types
|
|
126
|
-
```http
|
|
127
|
-
GET /users/1
|
|
128
|
-
Accept: application/vnd.api+json
|
|
129
|
-
|
|
130
|
-
HTTP/1.1 200 OK
|
|
131
|
-
Content-Type: application/vnd.api+json
|
|
132
|
-
|
|
133
|
-
{
|
|
134
|
-
"data": {
|
|
135
|
-
"id": "1",
|
|
136
|
-
"type": "users",
|
|
137
|
-
"attributes": {
|
|
138
|
-
"email": "john.doe@example.com",
|
|
139
|
-
"first_name": "John",
|
|
140
|
-
"last_name": "Doe",
|
|
141
|
-
"display_name": "johndoe",
|
|
142
|
-
"status": "active",
|
|
143
|
-
"full_name": "John Doe"
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
```
|