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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +1 -0
  3. data/.rubocop.yml +3 -3
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +2 -2
  6. data/CHANGELOG.md +31 -0
  7. data/Gemfile +3 -2
  8. data/Gemfile.lock +147 -124
  9. data/docs/README.md +24 -8
  10. data/docs/_sidebar.md +3 -0
  11. data/docs/components/controller.md +194 -21
  12. data/docs/components/model.md +193 -5
  13. data/docs/components/routes.md +28 -0
  14. data/docs/getting_started/quick_start.md +10 -3
  15. data/docs/index.html +1 -1
  16. data/docs/other_tools/query_runner.md +49 -0
  17. data/docs/other_tools/schema_dump.md +29 -0
  18. data/docs/testing/testing.md +3 -1
  19. data/graphql_rails.gemspec +5 -5
  20. data/lib/generators/graphql_rails/install_generator.rb +50 -0
  21. data/lib/generators/graphql_rails/templates/example_users_controller.erb +19 -0
  22. data/lib/generators/graphql_rails/templates/graphql_application_controller.erb +8 -0
  23. data/lib/generators/graphql_rails/templates/graphql_controller.erb +20 -0
  24. data/lib/generators/graphql_rails/templates/graphql_router.erb +19 -0
  25. data/lib/generators/graphql_rails/templates/graphql_router_spec.erb +21 -0
  26. data/lib/graphql_rails.rb +2 -0
  27. data/lib/graphql_rails/attributes/attributable.rb +20 -21
  28. data/lib/graphql_rails/attributes/attribute.rb +41 -4
  29. data/lib/graphql_rails/attributes/attribute_name_parser.rb +4 -4
  30. data/lib/graphql_rails/attributes/input_attribute.rb +24 -10
  31. data/lib/graphql_rails/attributes/input_type_parser.rb +24 -46
  32. data/lib/graphql_rails/attributes/type_parseable.rb +132 -0
  33. data/lib/graphql_rails/attributes/type_parser.rb +58 -54
  34. data/lib/graphql_rails/concerns/service.rb +19 -0
  35. data/lib/graphql_rails/controller.rb +26 -22
  36. data/lib/graphql_rails/controller/action.rb +12 -67
  37. data/lib/graphql_rails/controller/action_configuration.rb +70 -34
  38. data/lib/graphql_rails/controller/build_controller_action_resolver.rb +52 -0
  39. data/lib/graphql_rails/controller/build_controller_action_resolver/controller_action_resolver.rb +28 -0
  40. data/lib/graphql_rails/controller/configuration.rb +56 -5
  41. data/lib/graphql_rails/controller/log_controller_action.rb +11 -6
  42. data/lib/graphql_rails/controller/request.rb +29 -8
  43. data/lib/graphql_rails/controller/request/format_errors.rb +58 -0
  44. data/lib/graphql_rails/decorator/relation_decorator.rb +1 -5
  45. data/lib/graphql_rails/errors/custom_execution_error.rb +22 -0
  46. data/lib/graphql_rails/errors/execution_error.rb +6 -7
  47. data/lib/graphql_rails/errors/system_error.rb +14 -0
  48. data/lib/graphql_rails/errors/validation_error.rb +1 -5
  49. data/lib/graphql_rails/input_configurable.rb +47 -0
  50. data/lib/graphql_rails/model.rb +19 -4
  51. data/lib/graphql_rails/model/add_fields_to_graphql_type.rb +45 -0
  52. data/lib/graphql_rails/model/build_connection_type.rb +52 -0
  53. data/lib/graphql_rails/model/{configuration → build_connection_type}/count_items.rb +5 -5
  54. data/lib/graphql_rails/model/build_enum_type.rb +39 -10
  55. data/lib/graphql_rails/model/build_graphql_input_type.rb +8 -4
  56. data/lib/graphql_rails/model/call_graphql_model_method.rb +72 -0
  57. data/lib/graphql_rails/model/configurable.rb +6 -2
  58. data/lib/graphql_rails/model/configuration.rb +11 -10
  59. data/lib/graphql_rails/model/find_or_build_graphql_type.rb +64 -0
  60. data/lib/graphql_rails/model/find_or_build_graphql_type_class.rb +46 -0
  61. data/lib/graphql_rails/model/input.rb +10 -6
  62. data/lib/graphql_rails/query_runner.rb +68 -0
  63. data/lib/graphql_rails/railtie.rb +10 -0
  64. data/lib/graphql_rails/router.rb +40 -13
  65. data/lib/graphql_rails/router/resource_routes_builder.rb +10 -9
  66. data/lib/graphql_rails/router/route.rb +21 -6
  67. data/lib/graphql_rails/router/schema_builder.rb +30 -11
  68. data/lib/graphql_rails/rspec_controller_helpers.rb +6 -4
  69. data/lib/graphql_rails/tasks/dump_graphql_schema.rb +57 -0
  70. data/lib/graphql_rails/tasks/schema.rake +14 -0
  71. data/lib/graphql_rails/version.rb +1 -1
  72. metadata +48 -21
  73. data/lib/graphql_rails/controller/controller_function.rb +0 -50
  74. data/lib/graphql_rails/controller/format_results.rb +0 -36
  75. 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
- MyGraphqlSchema = GraphqlRails::Router.draw do
31
- # will create createUser, updateUser, deleteUser mutations and user, users queries.
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
- class UsersController < GraphqlRails::Controller
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).permit(search_fields!: SearchFieldsInput) # you can specify your own input fields
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
- MyGraphqlSchema = GraphqlRails::Router.draw do
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 handeled by `Admin::TranslationsController`
112
+ # `updateTranslations` route will be handled by `Admin::TranslationsController`
99
113
  mutation :updateTranslations, to: 'translations#update'
100
114
 
101
- # all :groups routes will be handeled by `Admin::GroupsController`
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
@@ -9,3 +9,6 @@
9
9
  * [Decorator](components/decorator)
10
10
  * [Logging and monitoring](logging_and_monitoring/logging_and_monitoring)
11
11
  * [Testing](testing/testing)
12
+ * Other tools
13
+ * [Schema Snapshot](other_tools/schema_dump)
14
+ * [Query Runner](other_tools/query_runner)
@@ -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(amount: :integer!)`
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']('components/decorator') for more details about working with active record and decorators.
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
- By default return type is determined by controller name. When you want to return some custom object, you can specify that with `returns` method:
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 require_auth_token
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']('components/decorator') for various options how you can decorate paginated 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
+ ```
@@ -17,13 +17,13 @@ end
17
17
 
18
18
  ## graphql
19
19
 
20
- This method must be called inside your model body. `grapqhl` is used for making your model convertible to graphql type.
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
- ## attribute type
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
- ### attribute property
57
+ #### attribute.type: using graphql-ruby objects
58
58
 
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:
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 description
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
+ ```