graphql_rails 0.8.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +20 -23
- data/docs/README.md +21 -5
- data/docs/_sidebar.md +3 -0
- data/docs/components/controller.md +174 -17
- data/docs/components/model.md +151 -3
- data/docs/components/routes.md +28 -0
- data/docs/getting_started/quick_start.md +9 -2
- data/docs/other_tools/query_runner.md +49 -0
- data/docs/other_tools/schema_dump.md +29 -0
- data/docs/testing/testing.md +3 -1
- data/graphql_rails.gemspec +1 -1
- data/lib/generators/graphql_rails/install_generator.rb +50 -0
- data/lib/generators/graphql_rails/templates/example_users_controller.erb +19 -0
- data/lib/generators/graphql_rails/templates/graphql_application_controller.erb +8 -0
- data/lib/generators/graphql_rails/templates/graphql_controller.erb +20 -0
- data/lib/generators/graphql_rails/templates/graphql_router.erb +19 -0
- data/lib/generators/graphql_rails/templates/graphql_router_spec.erb +18 -0
- data/lib/graphql_rails.rb +2 -0
- data/lib/graphql_rails/attributes/attributable.rb +16 -13
- data/lib/graphql_rails/attributes/attribute.rb +20 -3
- data/lib/graphql_rails/attributes/input_attribute.rb +20 -10
- data/lib/graphql_rails/attributes/input_type_parser.rb +24 -46
- data/lib/graphql_rails/attributes/type_parseable.rb +128 -0
- data/lib/graphql_rails/attributes/type_parser.rb +58 -54
- data/lib/graphql_rails/concerns/service.rb +15 -0
- data/lib/graphql_rails/controller.rb +20 -16
- data/lib/graphql_rails/controller/action.rb +10 -69
- data/lib/graphql_rails/controller/action_configuration.rb +70 -34
- data/lib/graphql_rails/controller/build_controller_action_resolver.rb +52 -0
- data/lib/graphql_rails/controller/build_controller_action_resolver/controller_action_resolver.rb +28 -0
- data/lib/graphql_rails/controller/configuration.rb +56 -5
- data/lib/graphql_rails/controller/log_controller_action.rb +4 -4
- data/lib/graphql_rails/controller/request.rb +29 -8
- data/lib/graphql_rails/controller/request/format_errors.rb +58 -0
- data/lib/graphql_rails/decorator/relation_decorator.rb +1 -1
- data/lib/graphql_rails/errors/custom_execution_error.rb +22 -0
- data/lib/graphql_rails/errors/execution_error.rb +6 -7
- data/lib/graphql_rails/errors/system_error.rb +14 -0
- data/lib/graphql_rails/errors/validation_error.rb +1 -5
- data/lib/graphql_rails/input_configurable.rb +47 -0
- data/lib/graphql_rails/model.rb +19 -4
- data/lib/graphql_rails/model/build_connection_type.rb +48 -0
- data/lib/graphql_rails/model/{configuration → build_connection_type}/count_items.rb +4 -4
- data/lib/graphql_rails/model/build_enum_type.rb +39 -10
- data/lib/graphql_rails/model/build_graphql_input_type.rb +7 -3
- data/lib/graphql_rails/model/build_graphql_type.rb +23 -7
- data/lib/graphql_rails/model/call_graphql_model_method.rb +59 -0
- data/lib/graphql_rails/model/configuration.rb +2 -6
- data/lib/graphql_rails/model/input.rb +10 -6
- data/lib/graphql_rails/query_runner.rb +68 -0
- data/lib/graphql_rails/railtie.rb +10 -0
- data/lib/graphql_rails/router.rb +40 -13
- data/lib/graphql_rails/router/resource_routes_builder.rb +2 -1
- data/lib/graphql_rails/router/route.rb +25 -6
- data/lib/graphql_rails/router/schema_builder.rb +26 -11
- data/lib/graphql_rails/rspec_controller_helpers.rb +4 -2
- data/lib/graphql_rails/tasks/dump_graphql_schema.rb +57 -0
- data/lib/graphql_rails/tasks/schema.rake +14 -0
- data/lib/graphql_rails/version.rb +1 -1
- metadata +29 -9
- data/lib/graphql_rails/controller/controller_function.rb +0 -50
- data/lib/graphql_rails/controller/format_results.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcc5df5d34e3bf317dd9bb07e2b846bf8dfa48e990258b4bb2f30ef73d049939
|
4
|
+
data.tar.gz: 6cd112b22a0d01f031dd2aba92efc390d44b209c8d6a428e257d1be99377f28c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59f24a1ad00e309c7617a6ed65200dc11f62680974f3de7ca4e36d96b0d8dab8f286c8c9c4b50dd4b70a375959187ce21d09a309075a4ffa009716d3b74e7df7
|
7
|
+
data.tar.gz: ca1500174b1443240db65e3b57dbe0616ad7038da3e6f833ca2979e2fb4de7074c8ce9671c55dfa07bb327f4469b7999b8f00769a686c8829abfcf2eb275b6e0
|
data/CHANGELOG.md
CHANGED
@@ -9,6 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
9
9
|
|
10
10
|
* Added/Changed/Deprecated/Removed/Fixed/Security: YOUR CHANGE HERE
|
11
11
|
|
12
|
+
## [1.0.0](2020-02-07)
|
13
|
+
|
14
|
+
* Added: "required" and "optional" flags for attribute
|
15
|
+
* Added: grouped routes
|
16
|
+
* Added: added argument to model.attribute
|
17
|
+
* Added: added graphql_context to model
|
18
|
+
* Removed: `action.can_return_nil` was removed, because it does no affect anymore
|
19
|
+
* Removed: default `action` model was removed. Now each action must have `returns` part
|
20
|
+
* Added: default router added. No need to assign value to constant on Router.draw
|
21
|
+
* Added: default action added. Now actions can have custom defaults
|
22
|
+
* Added: default controller model added. Now actions can be defined in more dynamic way
|
23
|
+
* Added: install generator. Now it's possible to generate boilerplate code
|
24
|
+
|
12
25
|
## [0.8.0] (2019-09-03)
|
13
26
|
|
14
27
|
* Added: permit_input action config with extended list of permitted input options
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
graphql_rails (0.
|
4
|
+
graphql_rails (1.0.0)
|
5
5
|
activesupport (>= 4)
|
6
|
-
graphql (
|
6
|
+
graphql (>= 1.9.12)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
@@ -60,18 +60,18 @@ GEM
|
|
60
60
|
url
|
61
61
|
coderay (1.1.2)
|
62
62
|
concurrent-ruby (1.1.5)
|
63
|
-
crass (1.0.
|
63
|
+
crass (1.0.5)
|
64
64
|
diff-lcs (1.3)
|
65
|
-
docile (1.3.
|
65
|
+
docile (1.3.2)
|
66
66
|
erubi (1.8.0)
|
67
67
|
globalid (0.4.2)
|
68
68
|
activesupport (>= 4.2.0)
|
69
|
-
graphql (1.9.
|
69
|
+
graphql (1.9.17)
|
70
70
|
i18n (1.6.0)
|
71
71
|
concurrent-ruby (~> 1.0)
|
72
|
-
jaro_winkler (1.5.
|
73
|
-
json (2.
|
74
|
-
loofah (2.
|
72
|
+
jaro_winkler (1.5.4)
|
73
|
+
json (2.3.0)
|
74
|
+
loofah (2.3.1)
|
75
75
|
crass (~> 1.0.2)
|
76
76
|
nokogiri (>= 1.5.9)
|
77
77
|
mail (2.7.1)
|
@@ -89,10 +89,10 @@ GEM
|
|
89
89
|
activemodel (>= 5.1, < 6.0.0)
|
90
90
|
mongo (>= 2.5.1, < 3.0.0)
|
91
91
|
nio4r (2.3.1)
|
92
|
-
nokogiri (1.10.
|
92
|
+
nokogiri (1.10.5)
|
93
93
|
mini_portile2 (~> 2.4.0)
|
94
|
-
parallel (1.
|
95
|
-
parser (2.
|
94
|
+
parallel (1.19.1)
|
95
|
+
parser (2.7.0.2)
|
96
96
|
ast (~> 2.4.0)
|
97
97
|
pry (0.12.2)
|
98
98
|
coderay (~> 1.1.0)
|
@@ -100,8 +100,7 @@ GEM
|
|
100
100
|
pry-byebug (3.7.0)
|
101
101
|
byebug (~> 11.0)
|
102
102
|
pry (~> 0.10)
|
103
|
-
|
104
|
-
rack (2.0.7)
|
103
|
+
rack (2.0.8)
|
105
104
|
rack-test (1.1.0)
|
106
105
|
rack (>= 1.0, < 3)
|
107
106
|
rails (5.2.2.1)
|
@@ -143,22 +142,20 @@ GEM
|
|
143
142
|
diff-lcs (>= 1.2.0, < 2.0)
|
144
143
|
rspec-support (~> 3.8.0)
|
145
144
|
rspec-support (3.8.0)
|
146
|
-
rubocop (0.
|
145
|
+
rubocop (0.79.0)
|
147
146
|
jaro_winkler (~> 1.5.1)
|
148
147
|
parallel (~> 1.10)
|
149
|
-
parser (>= 2.
|
150
|
-
psych (>= 3.1.0)
|
148
|
+
parser (>= 2.7.0.1)
|
151
149
|
rainbow (>= 2.2.2, < 4.0)
|
152
150
|
ruby-progressbar (~> 1.7)
|
153
|
-
unicode-display_width (>= 1.4.0, < 1.
|
151
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
154
152
|
rubocop-rspec (1.32.0)
|
155
153
|
rubocop (>= 0.60.0)
|
156
|
-
ruby-progressbar (1.10.
|
157
|
-
simplecov (0.
|
154
|
+
ruby-progressbar (1.10.1)
|
155
|
+
simplecov (0.18.1)
|
158
156
|
docile (~> 1.1)
|
159
|
-
|
160
|
-
|
161
|
-
simplecov-html (0.10.2)
|
157
|
+
simplecov-html (~> 0.11.0)
|
158
|
+
simplecov-html (0.11.0)
|
162
159
|
sprockets (3.7.2)
|
163
160
|
concurrent-ruby (~> 1.0)
|
164
161
|
rack (> 1, < 3)
|
@@ -170,7 +167,7 @@ GEM
|
|
170
167
|
thread_safe (0.3.6)
|
171
168
|
tzinfo (1.2.5)
|
172
169
|
thread_safe (~> 0.1)
|
173
|
-
unicode-display_width (1.
|
170
|
+
unicode-display_width (1.6.1)
|
174
171
|
url (0.3.2)
|
175
172
|
websocket-driver (0.7.1)
|
176
173
|
websocket-extensions (>= 0.1.0)
|
data/docs/README.md
CHANGED
@@ -22,12 +22,21 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
$ gem install graphql_rails
|
24
24
|
|
25
|
+
## Getting started
|
26
|
+
|
27
|
+
Execute:
|
28
|
+
|
29
|
+
$ bundle exec rails g graphql_rails:install
|
30
|
+
|
31
|
+
This will generate code which will let you start your graphql faster
|
32
|
+
|
25
33
|
## Usage
|
26
34
|
|
27
35
|
### Define GraphQL schema as RoR routes
|
28
36
|
|
29
37
|
```ruby
|
30
|
-
|
38
|
+
# config/graphql/routes.rb
|
39
|
+
GraphqlRails::Router.draw do
|
31
40
|
# will create createUser, updateUser, deleteUser mutations and user, users queries.
|
32
41
|
# expects that UsersController class exist
|
33
42
|
resources :users
|
@@ -41,6 +50,7 @@ end
|
|
41
50
|
### Define your Graphql model
|
42
51
|
|
43
52
|
```ruby
|
53
|
+
# app/models/user.rb
|
44
54
|
class User # works with any class including ActiveRecord
|
45
55
|
include GraphqlRails::Model
|
46
56
|
|
@@ -57,10 +67,12 @@ end
|
|
57
67
|
### Define controller
|
58
68
|
|
59
69
|
```ruby
|
60
|
-
|
70
|
+
# app/controllers/graphql/users_controller.rb
|
71
|
+
class Graphql::UsersController < GraphqlApplicationController
|
61
72
|
# graphql requires to describe which attributes controller action accepts and which returns
|
62
73
|
action(:change_user_password)
|
63
74
|
.permit(:password!, :id!) # Bang (!) indicates that attribute is required
|
75
|
+
.returns('User!')
|
64
76
|
|
65
77
|
def change_user_password
|
66
78
|
user = User.find(params[:id])
|
@@ -70,7 +82,9 @@ class UsersController < GraphqlRails::Controller
|
|
70
82
|
user # or SomeDecorator.new(user)
|
71
83
|
end
|
72
84
|
|
73
|
-
action(:search)
|
85
|
+
action(:search)
|
86
|
+
.permit(search_fields!: SearchFieldsInput) # you can specify your own input fields
|
87
|
+
.returns('[User!]!')
|
74
88
|
def search
|
75
89
|
end
|
76
90
|
end
|
@@ -79,7 +93,7 @@ end
|
|
79
93
|
## Routes
|
80
94
|
|
81
95
|
```ruby
|
82
|
-
|
96
|
+
GraphqlRails::Router.draw do
|
83
97
|
# generates `friend`, `createFriend`, `updateFriend`, `destroyFriend`, `friends` routes
|
84
98
|
resources :friends
|
85
99
|
resources :shops, only: [:show, :index] # generates `shop` and `shops` routes only
|
@@ -132,11 +146,13 @@ There are 3 helper methods:
|
|
132
146
|
|
133
147
|
```ruby
|
134
148
|
class MyGraphqlController
|
149
|
+
action(:create_user).permit(:full_name, :email).returns(User)
|
150
|
+
action(:index).returns('String')
|
151
|
+
|
135
152
|
def index
|
136
153
|
"Called from index: #{params[:message]}"
|
137
154
|
end
|
138
155
|
|
139
|
-
action(:create_user).permit(:full_name, :email)
|
140
156
|
def create_user
|
141
157
|
User.create!(params)
|
142
158
|
end
|
data/docs/_sidebar.md
CHANGED
@@ -155,22 +155,6 @@ class OrderController < GraphqlRails::Controller
|
|
155
155
|
end
|
156
156
|
```
|
157
157
|
|
158
|
-
### *can_return_nil*
|
159
|
-
|
160
|
-
By default it is expected that each controller action returns model or array of models. `nil` is not allowed. You can change that by adding `can_return_nil` like this:
|
161
|
-
|
162
|
-
```ruby
|
163
|
-
class UsersController < GraphqlRails::Controller
|
164
|
-
action(:show).permit(:email).can_return_nil
|
165
|
-
|
166
|
-
def show
|
167
|
-
user = User.find_by(email: params[:email])
|
168
|
-
return nil if user.blank?
|
169
|
-
user
|
170
|
-
end
|
171
|
-
end
|
172
|
-
```
|
173
|
-
|
174
158
|
### *paginated*
|
175
159
|
|
176
160
|
You can mark collection action as `paginated`. In this case controller will return relay connection type and it will be possible to return only partial results. No need to do anything on controller side (you should always return full list of items)
|
@@ -201,9 +185,29 @@ class UsersController < GraphqlRails::Controller
|
|
201
185
|
end
|
202
186
|
```
|
203
187
|
|
188
|
+
### *model*
|
189
|
+
|
190
|
+
If you want to define model dynamically, you can use combination of `model` and `returns_list` or `returns_single`. This is especially handy when model is used with `action_default`:
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
class OrdersController < GraphqlRails::Controller
|
194
|
+
model('Order')
|
195
|
+
action(:show).returns_single # returns `Order!`
|
196
|
+
action(:index).returns_list # returns `[Order!]!`
|
197
|
+
|
198
|
+
def show
|
199
|
+
Order.first
|
200
|
+
end
|
201
|
+
|
202
|
+
def index
|
203
|
+
Order.all
|
204
|
+
end
|
205
|
+
end
|
206
|
+
```
|
207
|
+
|
204
208
|
### *returns*
|
205
209
|
|
206
|
-
|
210
|
+
You must specify what each action will return. This is done with `returns` method:
|
207
211
|
|
208
212
|
```ruby
|
209
213
|
class UsersController < GraphqlRails::Controller
|
@@ -215,6 +219,32 @@ class UsersController < GraphqlRails::Controller
|
|
215
219
|
end
|
216
220
|
```
|
217
221
|
|
222
|
+
### *returns_list*
|
223
|
+
|
224
|
+
When you have defined `model` dynamically, you can use `returns_list` to indicate that action must return list without specifying model type for each action. By default list and inner types are required but you can change that with `required_list: false` and `required_inner: false`
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
class OrdersController < GraphqlRails::Controller
|
228
|
+
model('Order')
|
229
|
+
|
230
|
+
action(:index).returns_list(required_list: false, required_inner: false) # returns `[Order]`
|
231
|
+
action(:search).permit(:filter).returns_list # returns `[Order!]!`
|
232
|
+
end
|
233
|
+
```
|
234
|
+
|
235
|
+
### *returns_single*
|
236
|
+
|
237
|
+
When you have defined `model` dynamically, you can use `returns_single` to indicate that action must return single item without specifying model type for each action. By default return type is required, but you can change that by providing `required: false` flag:
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
class OrdersController < GraphqlRails::Controller
|
241
|
+
model('Order')
|
242
|
+
|
243
|
+
action(:show).returns_single(required: false) # returns `Order`
|
244
|
+
action(:update).permit(title: :string!).returns_single # returns `Order!`
|
245
|
+
end
|
246
|
+
```
|
247
|
+
|
218
248
|
### *describe*
|
219
249
|
|
220
250
|
If you want to improve graphql documentation, you can add description for each action. To do so, use `describe` method:
|
@@ -262,6 +292,39 @@ class UsersController < GraphqlRails::Controller
|
|
262
292
|
end
|
263
293
|
```
|
264
294
|
|
295
|
+
## *model*
|
296
|
+
|
297
|
+
`model` is just a shorter version of `action_default.model`. See `action.model` and `action_default` for more information:
|
298
|
+
|
299
|
+
```ruby
|
300
|
+
class OrdersController < GraphqlRails::Controller
|
301
|
+
model('Order')
|
302
|
+
action(:show).returns_single # returns `Order!`
|
303
|
+
action(:index).returns_list # returns `[Order!]!`
|
304
|
+
|
305
|
+
def show
|
306
|
+
Order.first
|
307
|
+
end
|
308
|
+
|
309
|
+
def index
|
310
|
+
Order.all
|
311
|
+
end
|
312
|
+
end
|
313
|
+
```
|
314
|
+
|
315
|
+
## *action_default*
|
316
|
+
|
317
|
+
Sometimes you want to have some shared attributes for all your actions. In order to make this possible you need to use `action_default`. It acts identical to `action` and is "inherited" by all actions defined after `action_default` part:
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
class UsersController < GraphqlRails::Controller
|
321
|
+
action_default.permit(token: :string!)
|
322
|
+
|
323
|
+
action(:update).returns('User!') # action(:update) has `permit(token: :string!)
|
324
|
+
action(:create).returns('User') # action(:create) has `permit(token: :string!)
|
325
|
+
end
|
326
|
+
```
|
327
|
+
|
265
328
|
## *before_action*
|
266
329
|
|
267
330
|
You can add `before_action` to run some filters before calling your controller action. Here is an example:
|
@@ -376,3 +439,97 @@ end
|
|
376
439
|
## decorating objects
|
377
440
|
|
378
441
|
See ['Decorating controller responses']('components/decorator') for various options how you can decorate paginated responses
|
442
|
+
|
443
|
+
## Rendering errors
|
444
|
+
|
445
|
+
### Rendering strings as errors
|
446
|
+
|
447
|
+
The simples way to render error is to provide list of error messages, like this:
|
448
|
+
|
449
|
+
```ruby
|
450
|
+
class UsersController < GraphqlRails::Controller
|
451
|
+
action(:update).permit(:id, input: 'UserInput!').returns('User!')
|
452
|
+
|
453
|
+
def update
|
454
|
+
user = User.find(params[:id])
|
455
|
+
|
456
|
+
if user.update(params[:input])
|
457
|
+
user
|
458
|
+
else
|
459
|
+
render(errors: ['Something went wrong'])
|
460
|
+
end
|
461
|
+
end
|
462
|
+
end
|
463
|
+
```
|
464
|
+
|
465
|
+
### Rendering validation errors
|
466
|
+
|
467
|
+
GraphqlRails controller has `#render` method which you can use to render errors:
|
468
|
+
|
469
|
+
```ruby
|
470
|
+
class UsersController < GraphqlRails::Controller
|
471
|
+
action(:update).permit(:id, input: 'UserInput!').returns('User!')
|
472
|
+
|
473
|
+
def update
|
474
|
+
user = User.find(params[:id])
|
475
|
+
|
476
|
+
if user.update(params[:input])
|
477
|
+
user
|
478
|
+
else
|
479
|
+
render(errors: user.errors)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
```
|
484
|
+
|
485
|
+
### Rendering errors with custom data
|
486
|
+
|
487
|
+
When you want to return errors with custom data, you can provide hash like this:
|
488
|
+
|
489
|
+
```ruby
|
490
|
+
class UsersController < GraphqlRails::Controller
|
491
|
+
action(:update).permit(:id, input: 'UserInput!').returns('User!')
|
492
|
+
|
493
|
+
def update
|
494
|
+
user = User.find(params[:id])
|
495
|
+
|
496
|
+
if user.update(params[:input])
|
497
|
+
user
|
498
|
+
else
|
499
|
+
render(
|
500
|
+
errors: [
|
501
|
+
{ message: 'Something went wrong', code: 500, type: 'fatal' },
|
502
|
+
{ message: 'Something went wrong', custom_param: true, ... },
|
503
|
+
]
|
504
|
+
)
|
505
|
+
end
|
506
|
+
end
|
507
|
+
end
|
508
|
+
```
|
509
|
+
|
510
|
+
### Raising custom error classes
|
511
|
+
|
512
|
+
If you want to have customized error classes you need to create errors which inherits from `GraphqlRails::ExecutionError`
|
513
|
+
|
514
|
+
```ruby
|
515
|
+
class MyCustomError < GraphqlRails::ExecutionError
|
516
|
+
def to_h
|
517
|
+
# this part will be rendered in graphl
|
518
|
+
{ something_custom: 'yes' }
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
class UsersController < GraphqlRails::Controller
|
523
|
+
action(:update).permit(:id, input: 'UserInput!').returns('User!')
|
524
|
+
|
525
|
+
def update
|
526
|
+
user = User.find(params[:id])
|
527
|
+
|
528
|
+
if user.update(params[:input])
|
529
|
+
user
|
530
|
+
else
|
531
|
+
raise MyCustomError, 'ups!'
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
```
|
data/docs/components/model.md
CHANGED
@@ -23,7 +23,7 @@ This method must be called inside your model body. `grapqhl` is used for making
|
|
23
23
|
|
24
24
|
Most commonly you will use `attribute` to make your model methods and attributes visible via graphql endpoint.
|
25
25
|
|
26
|
-
## attribute
|
26
|
+
## attribute.type
|
27
27
|
|
28
28
|
Some types can be determined by attribute name, so you can skip this attribute:
|
29
29
|
|
@@ -54,7 +54,7 @@ class User
|
|
54
54
|
end
|
55
55
|
```
|
56
56
|
|
57
|
-
### attribute
|
57
|
+
### attribute.property
|
58
58
|
|
59
59
|
By default graphql attribute names are expected to be same as model methods/attributes, but if you want to use different name on grapqhl side, you can use `propery` option:
|
60
60
|
|
@@ -72,7 +72,7 @@ class User
|
|
72
72
|
end
|
73
73
|
```
|
74
74
|
|
75
|
-
### attribute
|
75
|
+
### attribute.description
|
76
76
|
|
77
77
|
You can also describe each attribute and make graphql documentation even more readable. To do so, add `description` option:
|
78
78
|
|
@@ -86,6 +86,123 @@ class User
|
|
86
86
|
end
|
87
87
|
```
|
88
88
|
|
89
|
+
### attribute.permit
|
90
|
+
|
91
|
+
To define attributes which are accepted by each model method, you need to call `permit` method, like this:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
class User
|
95
|
+
include GraphqlRails::Model
|
96
|
+
|
97
|
+
graphql do |c|
|
98
|
+
c.attribute(:avatar_url).permit(size: :int!)
|
99
|
+
end
|
100
|
+
|
101
|
+
def avatar_url(size:)
|
102
|
+
# some code here
|
103
|
+
end
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
### attribute.permit_input
|
108
|
+
|
109
|
+
Allows to permit single input field. It allows to set additional options for each field.
|
110
|
+
|
111
|
+
#### attribute.permit_input.type
|
112
|
+
|
113
|
+
#### attribute.permit_input: required type
|
114
|
+
|
115
|
+
There are few ways how to mark field as required.
|
116
|
+
|
117
|
+
1. Adding exclamation mark at the end of type name:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
class User
|
121
|
+
include GraphqlRails::Model
|
122
|
+
|
123
|
+
graphql.attribute(:avatar_url).permit_input(:size, type: :int!)
|
124
|
+
end
|
125
|
+
```
|
126
|
+
|
127
|
+
2. Adding `required: true` options
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
class User
|
131
|
+
include GraphqlRails::Model
|
132
|
+
|
133
|
+
graphql.attribute(:avatar_url).permit_input(:size, type: :int, required: true)
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
137
|
+
#### attribute.permit_input.description
|
138
|
+
|
139
|
+
You can describe each input by adding `description` keyword argument:
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
class User
|
143
|
+
include GraphqlRails::Model
|
144
|
+
|
145
|
+
graphql.attribute(:avatar_url).permit_input(:size, description: 'max size of avatar')
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
149
|
+
#### *subtype*
|
150
|
+
|
151
|
+
`subtype` allows to specify which named input should be used. Here is an example:
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
class Image
|
155
|
+
graphql.input(:size_options) do |c|
|
156
|
+
c.attribute :width
|
157
|
+
c.attribute :height
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class User
|
162
|
+
graphql.attribute(:avatar_url).permit_input(:size, type: Image, subtype: :size_options)
|
163
|
+
end
|
164
|
+
```
|
165
|
+
|
166
|
+
### attribute.paginated
|
167
|
+
|
168
|
+
You can mark collection method as `paginated`. In this case method will return relay connection type and it will be possible to return only partial results. No need to do anything on method side (you should always return full list of items)
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
class User
|
172
|
+
include GraphqlRails::Model
|
173
|
+
|
174
|
+
graphql.attribute :items, type: '[Item]', paginatted: true
|
175
|
+
|
176
|
+
def items
|
177
|
+
Item.all
|
178
|
+
end
|
179
|
+
end
|
180
|
+
```
|
181
|
+
|
182
|
+
### attribute.required
|
183
|
+
|
184
|
+
You can mark attribute as required using `required` method:
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
class User
|
188
|
+
include GraphqlRails::Model
|
189
|
+
|
190
|
+
graphql.attribute(:item).type('Item').required
|
191
|
+
end
|
192
|
+
```
|
193
|
+
|
194
|
+
### attribute.optional
|
195
|
+
|
196
|
+
You can mark attribute as optional using `optional` method:
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
class User
|
200
|
+
include GraphqlRails::Model
|
201
|
+
|
202
|
+
graphql.attribute(:item).type('Item').optional
|
203
|
+
end
|
204
|
+
```
|
205
|
+
|
89
206
|
### "attribute" configuration with chainable methods
|
90
207
|
|
91
208
|
If your attribute definition is complex, you can define attribute in more eye-friendly chainable way with:
|
@@ -271,3 +388,34 @@ class User
|
|
271
388
|
end
|
272
389
|
end
|
273
390
|
```
|
391
|
+
|
392
|
+
## graphql_context
|
393
|
+
|
394
|
+
It's possible to access graphql_context in your model using method `graphql_context`:
|
395
|
+
|
396
|
+
```ruby
|
397
|
+
class User
|
398
|
+
include GraphqlRails::Model
|
399
|
+
|
400
|
+
def method_with_context
|
401
|
+
graphql_context[:some_data]
|
402
|
+
end
|
403
|
+
end
|
404
|
+
```
|
405
|
+
|
406
|
+
Keep in mind that this value will be set only during graphql execution, but in tests this value will be `nil`. To avoid this, you need to set `show_graphql_context` manually like this:
|
407
|
+
|
408
|
+
```ruby
|
409
|
+
class User
|
410
|
+
include GraphqlRails::Model
|
411
|
+
|
412
|
+
def show_graphql_context
|
413
|
+
graphql_context[:data]
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
user = User.new(...)
|
418
|
+
user.show_graphql_context #=> NoMethodError: undefined method `[]' for nil:NilClass
|
419
|
+
user.graphql_context = { data: 'goes to context' }
|
420
|
+
user.show_graphql_context #=> { data: 'goes to context' }
|
421
|
+
```
|