graphql_rails 0.8.0 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hound.yml +1 -0
- data/.rubocop.yml +3 -3
- data/.ruby-version +1 -1
- data/.travis.yml +2 -2
- data/CHANGELOG.md +31 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +147 -124
- data/docs/README.md +24 -8
- data/docs/_sidebar.md +3 -0
- data/docs/components/controller.md +194 -21
- data/docs/components/model.md +193 -5
- data/docs/components/routes.md +28 -0
- data/docs/getting_started/quick_start.md +10 -3
- data/docs/index.html +1 -1
- 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 +5 -5
- 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 +21 -0
- data/lib/graphql_rails.rb +2 -0
- data/lib/graphql_rails/attributes/attributable.rb +20 -21
- data/lib/graphql_rails/attributes/attribute.rb +41 -4
- data/lib/graphql_rails/attributes/attribute_name_parser.rb +4 -4
- data/lib/graphql_rails/attributes/input_attribute.rb +24 -10
- data/lib/graphql_rails/attributes/input_type_parser.rb +24 -46
- data/lib/graphql_rails/attributes/type_parseable.rb +132 -0
- data/lib/graphql_rails/attributes/type_parser.rb +58 -54
- data/lib/graphql_rails/concerns/service.rb +19 -0
- data/lib/graphql_rails/controller.rb +26 -22
- data/lib/graphql_rails/controller/action.rb +12 -67
- 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 +11 -6
- 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 -5
- 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/add_fields_to_graphql_type.rb +45 -0
- data/lib/graphql_rails/model/build_connection_type.rb +52 -0
- data/lib/graphql_rails/model/{configuration → build_connection_type}/count_items.rb +5 -5
- data/lib/graphql_rails/model/build_enum_type.rb +39 -10
- data/lib/graphql_rails/model/build_graphql_input_type.rb +8 -4
- data/lib/graphql_rails/model/call_graphql_model_method.rb +72 -0
- data/lib/graphql_rails/model/configurable.rb +6 -2
- data/lib/graphql_rails/model/configuration.rb +11 -10
- data/lib/graphql_rails/model/find_or_build_graphql_type.rb +64 -0
- data/lib/graphql_rails/model/find_or_build_graphql_type_class.rb +46 -0
- 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 +10 -9
- data/lib/graphql_rails/router/route.rb +21 -6
- data/lib/graphql_rails/router/schema_builder.rb +30 -11
- data/lib/graphql_rails/rspec_controller_helpers.rb +6 -4
- 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 +48 -21
- data/lib/graphql_rails/controller/controller_function.rb +0 -50
- data/lib/graphql_rails/controller/format_results.rb +0 -36
- data/lib/graphql_rails/model/build_graphql_type.rb +0 -37
data/docs/README.md
CHANGED
@@ -22,13 +22,22 @@ 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
|
-
|
31
|
-
|
38
|
+
# config/graphql/routes.rb
|
39
|
+
GraphqlRails::Router.draw do
|
40
|
+
# will create createUser, updateUser, destroyUser mutations and user, users queries.
|
32
41
|
# expects that UsersController class exist
|
33
42
|
resources :users
|
34
43
|
|
@@ -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
|
@@ -95,10 +109,10 @@ MyGraphqlSchema = GraphqlRails::Router.draw do
|
|
95
109
|
|
96
110
|
# you can use namespaced controllers too:
|
97
111
|
scope module: 'admin' do
|
98
|
-
# `updateTranslations` route will be
|
112
|
+
# `updateTranslations` route will be handled by `Admin::TranslationsController`
|
99
113
|
mutation :updateTranslations, to: 'translations#update'
|
100
114
|
|
101
|
-
# all :groups routes will be
|
115
|
+
# all :groups routes will be handled by `Admin::GroupsController`
|
102
116
|
resources :groups
|
103
117
|
end
|
104
118
|
end
|
@@ -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
@@ -78,7 +78,7 @@ Specifies input type:
|
|
78
78
|
class OrderController < GraphqlRails::Controller
|
79
79
|
action(:create)
|
80
80
|
.permit_input(:price, type: :integer!)
|
81
|
-
# Same as `.permit(
|
81
|
+
# Same as `.permit(price: :integer!)`
|
82
82
|
end
|
83
83
|
```
|
84
84
|
|
@@ -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)
|
@@ -185,7 +169,7 @@ class UsersController < GraphqlRails::Controller
|
|
185
169
|
end
|
186
170
|
```
|
187
171
|
|
188
|
-
Also check ['decorating controller responses'](
|
172
|
+
Also check ['decorating controller responses'](components/decorator) for more details about working with active record and decorators.
|
189
173
|
|
190
174
|
#### *max_page_size*
|
191
175
|
|
@@ -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,48 @@ class UsersController < GraphqlRails::Controller
|
|
215
219
|
end
|
216
220
|
```
|
217
221
|
|
222
|
+
You can also return raw graphql-ruby types:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
# raw graphql-ruby type:
|
226
|
+
class OrderType < GraphQL::Schema::Object
|
227
|
+
graphql_name 'Order'
|
228
|
+
field :id, ID
|
229
|
+
end
|
230
|
+
|
231
|
+
class UsersController < GraphqlRails::Controller
|
232
|
+
action(:last_order).permit(:id).returns(OrderType)
|
233
|
+
end
|
234
|
+
```
|
235
|
+
|
236
|
+
Check [graphql-ruby documentation](https://graphql-ruby.org) for more details about graphql-ruby types.
|
237
|
+
|
238
|
+
### *returns_list*
|
239
|
+
|
240
|
+
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`
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
class OrdersController < GraphqlRails::Controller
|
244
|
+
model('Order')
|
245
|
+
|
246
|
+
action(:index).returns_list(required_list: false, required_inner: false) # returns `[Order]`
|
247
|
+
action(:search).permit(:filter).returns_list # returns `[Order!]!`
|
248
|
+
end
|
249
|
+
```
|
250
|
+
|
251
|
+
### *returns_single*
|
252
|
+
|
253
|
+
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:
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
class OrdersController < GraphqlRails::Controller
|
257
|
+
model('Order')
|
258
|
+
|
259
|
+
action(:show).returns_single(required: false) # returns `Order`
|
260
|
+
action(:update).permit(title: :string!).returns_single # returns `Order!`
|
261
|
+
end
|
262
|
+
```
|
263
|
+
|
218
264
|
### *describe*
|
219
265
|
|
220
266
|
If you want to improve graphql documentation, you can add description for each action. To do so, use `describe` method:
|
@@ -262,6 +308,39 @@ class UsersController < GraphqlRails::Controller
|
|
262
308
|
end
|
263
309
|
```
|
264
310
|
|
311
|
+
## *model*
|
312
|
+
|
313
|
+
`model` is just a shorter version of `action_default.model`. See `action.model` and `action_default` for more information:
|
314
|
+
|
315
|
+
```ruby
|
316
|
+
class OrdersController < GraphqlRails::Controller
|
317
|
+
model('Order')
|
318
|
+
action(:show).returns_single # returns `Order!`
|
319
|
+
action(:index).returns_list # returns `[Order!]!`
|
320
|
+
|
321
|
+
def show
|
322
|
+
Order.first
|
323
|
+
end
|
324
|
+
|
325
|
+
def index
|
326
|
+
Order.all
|
327
|
+
end
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
## *action_default*
|
332
|
+
|
333
|
+
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:
|
334
|
+
|
335
|
+
```ruby
|
336
|
+
class UsersController < GraphqlRails::Controller
|
337
|
+
action_default.permit(token: :string!)
|
338
|
+
|
339
|
+
action(:update).returns('User!') # action(:update) has `permit(token: :string!)
|
340
|
+
action(:create).returns('User') # action(:create) has `permit(token: :string!)
|
341
|
+
end
|
342
|
+
```
|
343
|
+
|
265
344
|
## *before_action*
|
266
345
|
|
267
346
|
You can add `before_action` to run some filters before calling your controller action. Here is an example:
|
@@ -367,7 +446,7 @@ class UsersController < GraphqlRails::Controller
|
|
367
446
|
raise 'Not authenticated' unless User.where(token: params[:token]).exist?
|
368
447
|
end
|
369
448
|
|
370
|
-
def
|
449
|
+
def require_admin_token
|
371
450
|
raise 'Admin not authenticated' unless Admin.where(token: params[:admin_token]).exist?
|
372
451
|
end
|
373
452
|
end
|
@@ -375,4 +454,98 @@ end
|
|
375
454
|
|
376
455
|
## decorating objects
|
377
456
|
|
378
|
-
See ['Decorating controller responses'](
|
457
|
+
See ['Decorating controller responses'](components/decorator) for various options how you can decorate paginated responses
|
458
|
+
|
459
|
+
## Rendering errors
|
460
|
+
|
461
|
+
### Rendering strings as errors
|
462
|
+
|
463
|
+
The simplest way to render an error is to provide a list of error messages, like this:
|
464
|
+
|
465
|
+
```ruby
|
466
|
+
class UsersController < GraphqlRails::Controller
|
467
|
+
action(:update).permit(:id, input: 'UserInput!').returns('User!')
|
468
|
+
|
469
|
+
def update
|
470
|
+
user = User.find(params[:id])
|
471
|
+
|
472
|
+
if user.update(params[:input])
|
473
|
+
user
|
474
|
+
else
|
475
|
+
render(errors: ['Something went wrong'])
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
```
|
480
|
+
|
481
|
+
### Rendering validation errors
|
482
|
+
|
483
|
+
GraphqlRails controller has `#render` method which you can use to render errors:
|
484
|
+
|
485
|
+
```ruby
|
486
|
+
class UsersController < GraphqlRails::Controller
|
487
|
+
action(:update).permit(:id, input: 'UserInput!').returns('User!')
|
488
|
+
|
489
|
+
def update
|
490
|
+
user = User.find(params[:id])
|
491
|
+
|
492
|
+
if user.update(params[:input])
|
493
|
+
user
|
494
|
+
else
|
495
|
+
render(errors: user.errors)
|
496
|
+
end
|
497
|
+
end
|
498
|
+
end
|
499
|
+
```
|
500
|
+
|
501
|
+
### Rendering errors with custom data
|
502
|
+
|
503
|
+
When you want to return errors with custom data, you can provide hash like this:
|
504
|
+
|
505
|
+
```ruby
|
506
|
+
class UsersController < GraphqlRails::Controller
|
507
|
+
action(:update).permit(:id, input: 'UserInput!').returns('User!')
|
508
|
+
|
509
|
+
def update
|
510
|
+
user = User.find(params[:id])
|
511
|
+
|
512
|
+
if user.update(params[:input])
|
513
|
+
user
|
514
|
+
else
|
515
|
+
render(
|
516
|
+
errors: [
|
517
|
+
{ message: 'Something went wrong', code: 500, type: 'fatal' },
|
518
|
+
{ message: 'Something went wrong', custom_param: true, ... },
|
519
|
+
]
|
520
|
+
)
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|
524
|
+
```
|
525
|
+
|
526
|
+
### Raising custom error classes
|
527
|
+
|
528
|
+
If you want to have customized error classes you need to create errors which inherit from `GraphqlRails::ExecutionError`
|
529
|
+
|
530
|
+
```ruby
|
531
|
+
class MyCustomError < GraphqlRails::ExecutionError
|
532
|
+
def to_h
|
533
|
+
# this part will be rendered in graphql
|
534
|
+
{ something_custom: 'yes' }
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
class UsersController < GraphqlRails::Controller
|
539
|
+
action(:update).permit(:id, input: 'UserInput!').returns('User!')
|
540
|
+
|
541
|
+
def update
|
542
|
+
user = User.find(params[:id])
|
543
|
+
|
544
|
+
if user.update(params[:input])
|
545
|
+
user
|
546
|
+
else
|
547
|
+
raise MyCustomError, 'ups!'
|
548
|
+
end
|
549
|
+
end
|
550
|
+
end
|
551
|
+
```
|
data/docs/components/model.md
CHANGED
@@ -17,13 +17,13 @@ end
|
|
17
17
|
|
18
18
|
## graphql
|
19
19
|
|
20
|
-
This method must be called inside your model body. `
|
20
|
+
This method must be called inside your model body. `graphql` is used for making your model convertible to graphql type.
|
21
21
|
|
22
22
|
## attribute
|
23
23
|
|
24
24
|
Most commonly you will use `attribute` to make your model methods and attributes visible via graphql endpoint.
|
25
25
|
|
26
|
-
|
26
|
+
### attribute.type
|
27
27
|
|
28
28
|
Some types can be determined by attribute name, so you can skip this attribute:
|
29
29
|
|
@@ -54,9 +54,33 @@ class User
|
|
54
54
|
end
|
55
55
|
```
|
56
56
|
|
57
|
-
|
57
|
+
#### attribute.type: using graphql-ruby objects
|
58
58
|
|
59
|
-
|
59
|
+
You can also use raw graphql-ruby objects as attribute types. Here is an example:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
# raw graphql-ruby type:
|
63
|
+
class AddressType < GraphQL::Schema::Object
|
64
|
+
graphql_name 'Address'
|
65
|
+
|
66
|
+
field :city, String, null: false
|
67
|
+
field :street_name, String, null: false
|
68
|
+
field :street_number, Integer
|
69
|
+
end
|
70
|
+
|
71
|
+
# GraphqlRails model:
|
72
|
+
class User
|
73
|
+
include GraphqlRails::Model
|
74
|
+
|
75
|
+
graphql.attribute :address, type: AddressType, required: true
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
Check [graphql-ruby documentation](https://graphql-ruby.org) for more details about graphql-ruby types.
|
80
|
+
|
81
|
+
### attribute.property
|
82
|
+
|
83
|
+
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 `property` option:
|
60
84
|
|
61
85
|
```ruby
|
62
86
|
class User
|
@@ -72,7 +96,7 @@ class User
|
|
72
96
|
end
|
73
97
|
```
|
74
98
|
|
75
|
-
### attribute
|
99
|
+
### attribute.description
|
76
100
|
|
77
101
|
You can also describe each attribute and make graphql documentation even more readable. To do so, add `description` option:
|
78
102
|
|
@@ -86,6 +110,139 @@ class User
|
|
86
110
|
end
|
87
111
|
```
|
88
112
|
|
113
|
+
### attribute.options
|
114
|
+
|
115
|
+
Allows passing options to attribute definition. Available options:
|
116
|
+
|
117
|
+
* `attribute_name_format` - if `:original` value is passed, it will not camelCase attribute name.
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
class User
|
121
|
+
include GraphqlRails::Model
|
122
|
+
|
123
|
+
graphql do |c|
|
124
|
+
c.attribute :first_name # will be accessible as firstName from client side
|
125
|
+
c.attribute :first_name, options: { attribute_name_format: :original } # will be accessible as first_name from client side
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
### attribute.permit
|
130
|
+
|
131
|
+
To define attributes which are accepted by each model method, you need to call `permit` method, like this:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
class User
|
135
|
+
include GraphqlRails::Model
|
136
|
+
|
137
|
+
graphql do |c|
|
138
|
+
c.attribute(:avatar_url).permit(size: :int!)
|
139
|
+
end
|
140
|
+
|
141
|
+
def avatar_url(size:)
|
142
|
+
# some code here
|
143
|
+
end
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
### attribute.permit_input
|
148
|
+
|
149
|
+
Allows to permit single input field. It allows to set additional options for each field.
|
150
|
+
|
151
|
+
#### attribute.permit_input.type
|
152
|
+
|
153
|
+
#### attribute.permit_input: required type
|
154
|
+
|
155
|
+
There are few ways how to mark field as required.
|
156
|
+
|
157
|
+
1. Adding exclamation mark at the end of type name:
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
class User
|
161
|
+
include GraphqlRails::Model
|
162
|
+
|
163
|
+
graphql.attribute(:avatar_url).permit_input(:size, type: :int!)
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
167
|
+
2. Adding `required: true` options
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
class User
|
171
|
+
include GraphqlRails::Model
|
172
|
+
|
173
|
+
graphql.attribute(:avatar_url).permit_input(:size, type: :int, required: true)
|
174
|
+
end
|
175
|
+
```
|
176
|
+
|
177
|
+
#### attribute.permit_input.description
|
178
|
+
|
179
|
+
You can describe each input by adding `description` keyword argument:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
class User
|
183
|
+
include GraphqlRails::Model
|
184
|
+
|
185
|
+
graphql.attribute(:avatar_url).permit_input(:size, description: 'max size of avatar')
|
186
|
+
end
|
187
|
+
```
|
188
|
+
|
189
|
+
#### *subtype*
|
190
|
+
|
191
|
+
`subtype` allows to specify which named input should be used. Here is an example:
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
class Image
|
195
|
+
graphql.input(:size_options) do |c|
|
196
|
+
c.attribute :width
|
197
|
+
c.attribute :height
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
class User
|
202
|
+
graphql.attribute(:avatar_url).permit_input(:size, type: Image, subtype: :size_options)
|
203
|
+
end
|
204
|
+
```
|
205
|
+
|
206
|
+
### attribute.paginated
|
207
|
+
|
208
|
+
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)
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
class User
|
212
|
+
include GraphqlRails::Model
|
213
|
+
|
214
|
+
graphql.attribute :items, type: '[Item]', paginatted: true
|
215
|
+
|
216
|
+
def items
|
217
|
+
Item.all
|
218
|
+
end
|
219
|
+
end
|
220
|
+
```
|
221
|
+
|
222
|
+
### attribute.required
|
223
|
+
|
224
|
+
You can mark attribute as required using `required` method:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
class User
|
228
|
+
include GraphqlRails::Model
|
229
|
+
|
230
|
+
graphql.attribute(:item).type('Item').required
|
231
|
+
end
|
232
|
+
```
|
233
|
+
|
234
|
+
### attribute.optional
|
235
|
+
|
236
|
+
You can mark attribute as optional using `optional` method:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
class User
|
240
|
+
include GraphqlRails::Model
|
241
|
+
|
242
|
+
graphql.attribute(:item).type('Item').optional
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
89
246
|
### "attribute" configuration with chainable methods
|
90
247
|
|
91
248
|
If your attribute definition is complex, you can define attribute in more eye-friendly chainable way with:
|
@@ -271,3 +428,34 @@ class User
|
|
271
428
|
end
|
272
429
|
end
|
273
430
|
```
|
431
|
+
|
432
|
+
## graphql_context
|
433
|
+
|
434
|
+
It's possible to access graphql_context in your model using method `graphql_context`:
|
435
|
+
|
436
|
+
```ruby
|
437
|
+
class User
|
438
|
+
include GraphqlRails::Model
|
439
|
+
|
440
|
+
def method_with_context
|
441
|
+
graphql_context[:some_data]
|
442
|
+
end
|
443
|
+
end
|
444
|
+
```
|
445
|
+
|
446
|
+
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:
|
447
|
+
|
448
|
+
```ruby
|
449
|
+
class User
|
450
|
+
include GraphqlRails::Model
|
451
|
+
|
452
|
+
def show_graphql_context
|
453
|
+
graphql_context[:data]
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
user = User.new(...)
|
458
|
+
user.show_graphql_context #=> NoMethodError: undefined method `[]' for nil:NilClass
|
459
|
+
user.graphql_context = { data: 'goes to context' }
|
460
|
+
user.show_graphql_context #=> { data: 'goes to context' }
|
461
|
+
```
|