graphql_rails 3.0.0 → 3.1.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/.github/workflows/ruby.yml +1 -1
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +147 -125
- data/docs/components/decorator.md +31 -1
- data/graphql_rails.gemspec +1 -1
- data/lib/graphql_rails/concerns/service.rb +1 -5
- data/lib/graphql_rails/controller/action_hooks_runner.rb +7 -2
- data/lib/graphql_rails/controller/request.rb +1 -0
- data/lib/graphql_rails/controller.rb +1 -1
- data/lib/graphql_rails/decorator/relation_decorator.rb +12 -6
- data/lib/graphql_rails/decorator.rb +10 -6
- data/lib/graphql_rails/model/add_fields_to_graphql_type.rb +2 -1
- data/lib/graphql_rails/model/call_graphql_model_method.rb +16 -4
- data/lib/graphql_rails/model/direct_field_resolver.rb +31 -0
- data/lib/graphql_rails/router/schema_builder.rb +2 -0
- data/lib/graphql_rails/router.rb +1 -1
- data/lib/graphql_rails/version.rb +1 -1
- metadata +11 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afbec95cbbadb5f167ecc59f8e21fd4e7ab4285f97a6d6bc847129c2de03fe43
|
4
|
+
data.tar.gz: dc1434040422eda6fe0dca6ba123e6ff51a37df658bcd314be834f67c97f9d66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57801abd718d1e5bac281e01a6dfa7e54bc3da9def20f479c6c028b5b8ab8e77dbc7cd2c7e6c6a1ff6ba48cfbc7e81e0b23bb6da81f40050fbc69d6ed460af3a
|
7
|
+
data.tar.gz: 23c740466516ec437da7d7a8d909958b63d3aaca75dc3c53d748f5c7c79097c8c86c801396f4ba9e95b8fd16ae5f8cbcb9f59dcf06e0f69050cfcdc1e0ddb0cc
|
data/.github/workflows/ruby.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -9,6 +9,15 @@ 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
|
+
## [3.1.0](2025-05-26)
|
13
|
+
|
14
|
+
* Added: Allow passing custom decorator build strategy
|
15
|
+
* Added: Tracer support to router
|
16
|
+
* Fixed: Better handle render in controller hooks
|
17
|
+
* Fixed: Reduce memory allocations when defining attributes
|
18
|
+
* Updated: GraphQL and gems version dependencies
|
19
|
+
* Updated: Bump rexml from 3.2.8 to 3.3.9
|
20
|
+
|
12
21
|
## [3.0.0](2024-05-31)
|
13
22
|
|
14
23
|
* Added: `input.attribute.property` method which allows aliasing input parameter keys
|
data/Gemfile.lock
CHANGED
@@ -3,165 +3,186 @@ PATH
|
|
3
3
|
specs:
|
4
4
|
graphql_rails (3.0.0)
|
5
5
|
activesupport (>= 4)
|
6
|
-
graphql (
|
6
|
+
graphql (~> 2)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
actioncable (6.1.7.
|
12
|
-
actionpack (= 6.1.7.
|
13
|
-
activesupport (= 6.1.7.
|
11
|
+
actioncable (6.1.7.10)
|
12
|
+
actionpack (= 6.1.7.10)
|
13
|
+
activesupport (= 6.1.7.10)
|
14
14
|
nio4r (~> 2.0)
|
15
15
|
websocket-driver (>= 0.6.1)
|
16
|
-
actionmailbox (6.1.7.
|
17
|
-
actionpack (= 6.1.7.
|
18
|
-
activejob (= 6.1.7.
|
19
|
-
activerecord (= 6.1.7.
|
20
|
-
activestorage (= 6.1.7.
|
21
|
-
activesupport (= 6.1.7.
|
16
|
+
actionmailbox (6.1.7.10)
|
17
|
+
actionpack (= 6.1.7.10)
|
18
|
+
activejob (= 6.1.7.10)
|
19
|
+
activerecord (= 6.1.7.10)
|
20
|
+
activestorage (= 6.1.7.10)
|
21
|
+
activesupport (= 6.1.7.10)
|
22
22
|
mail (>= 2.7.1)
|
23
|
-
actionmailer (6.1.7.
|
24
|
-
actionpack (= 6.1.7.
|
25
|
-
actionview (= 6.1.7.
|
26
|
-
activejob (= 6.1.7.
|
27
|
-
activesupport (= 6.1.7.
|
23
|
+
actionmailer (6.1.7.10)
|
24
|
+
actionpack (= 6.1.7.10)
|
25
|
+
actionview (= 6.1.7.10)
|
26
|
+
activejob (= 6.1.7.10)
|
27
|
+
activesupport (= 6.1.7.10)
|
28
28
|
mail (~> 2.5, >= 2.5.4)
|
29
29
|
rails-dom-testing (~> 2.0)
|
30
|
-
actionpack (6.1.7.
|
31
|
-
actionview (= 6.1.7.
|
32
|
-
activesupport (= 6.1.7.
|
30
|
+
actionpack (6.1.7.10)
|
31
|
+
actionview (= 6.1.7.10)
|
32
|
+
activesupport (= 6.1.7.10)
|
33
33
|
rack (~> 2.0, >= 2.0.9)
|
34
34
|
rack-test (>= 0.6.3)
|
35
35
|
rails-dom-testing (~> 2.0)
|
36
36
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
37
|
-
actiontext (6.1.7.
|
38
|
-
actionpack (= 6.1.7.
|
39
|
-
activerecord (= 6.1.7.
|
40
|
-
activestorage (= 6.1.7.
|
41
|
-
activesupport (= 6.1.7.
|
37
|
+
actiontext (6.1.7.10)
|
38
|
+
actionpack (= 6.1.7.10)
|
39
|
+
activerecord (= 6.1.7.10)
|
40
|
+
activestorage (= 6.1.7.10)
|
41
|
+
activesupport (= 6.1.7.10)
|
42
42
|
nokogiri (>= 1.8.5)
|
43
|
-
actionview (6.1.7.
|
44
|
-
activesupport (= 6.1.7.
|
43
|
+
actionview (6.1.7.10)
|
44
|
+
activesupport (= 6.1.7.10)
|
45
45
|
builder (~> 3.1)
|
46
46
|
erubi (~> 1.4)
|
47
47
|
rails-dom-testing (~> 2.0)
|
48
48
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
49
|
-
activejob (6.1.7.
|
50
|
-
activesupport (= 6.1.7.
|
49
|
+
activejob (6.1.7.10)
|
50
|
+
activesupport (= 6.1.7.10)
|
51
51
|
globalid (>= 0.3.6)
|
52
|
-
activemodel (6.1.7.
|
53
|
-
activesupport (= 6.1.7.
|
54
|
-
activerecord (6.1.7.
|
55
|
-
activemodel (= 6.1.7.
|
56
|
-
activesupport (= 6.1.7.
|
57
|
-
activestorage (6.1.7.
|
58
|
-
actionpack (= 6.1.7.
|
59
|
-
activejob (= 6.1.7.
|
60
|
-
activerecord (= 6.1.7.
|
61
|
-
activesupport (= 6.1.7.
|
52
|
+
activemodel (6.1.7.10)
|
53
|
+
activesupport (= 6.1.7.10)
|
54
|
+
activerecord (6.1.7.10)
|
55
|
+
activemodel (= 6.1.7.10)
|
56
|
+
activesupport (= 6.1.7.10)
|
57
|
+
activestorage (6.1.7.10)
|
58
|
+
actionpack (= 6.1.7.10)
|
59
|
+
activejob (= 6.1.7.10)
|
60
|
+
activerecord (= 6.1.7.10)
|
61
|
+
activesupport (= 6.1.7.10)
|
62
62
|
marcel (~> 1.0)
|
63
63
|
mini_mime (>= 1.1.0)
|
64
|
-
activesupport (6.1.7.
|
64
|
+
activesupport (6.1.7.10)
|
65
65
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
66
66
|
i18n (>= 1.6, < 2)
|
67
67
|
minitest (>= 5.1)
|
68
68
|
tzinfo (~> 2.0)
|
69
69
|
zeitwerk (~> 2.3)
|
70
|
-
ast (2.4.
|
71
|
-
|
72
|
-
|
70
|
+
ast (2.4.3)
|
71
|
+
base64 (0.2.0)
|
72
|
+
bson (5.0.2)
|
73
|
+
builder (3.3.0)
|
73
74
|
byebug (11.1.3)
|
74
75
|
codecov (0.6.0)
|
75
76
|
simplecov (>= 0.15, < 0.22)
|
76
77
|
coderay (1.1.3)
|
77
|
-
concurrent-ruby (1.3.
|
78
|
+
concurrent-ruby (1.3.5)
|
78
79
|
crass (1.0.6)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
80
|
+
date (3.4.1)
|
81
|
+
diff-lcs (1.6.1)
|
82
|
+
docile (1.4.1)
|
83
|
+
erubi (1.13.1)
|
84
|
+
fiber-storage (1.0.0)
|
85
|
+
globalid (1.2.1)
|
86
|
+
activesupport (>= 6.1)
|
87
|
+
graphql (2.4.15)
|
88
|
+
base64
|
89
|
+
fiber-storage
|
90
|
+
logger
|
91
|
+
i18n (1.14.7)
|
87
92
|
concurrent-ruby (~> 1.0)
|
88
|
-
|
93
|
+
logger (1.6.6)
|
94
|
+
loofah (2.24.0)
|
89
95
|
crass (~> 1.0.2)
|
90
|
-
nokogiri (>= 1.
|
91
|
-
mail (2.
|
96
|
+
nokogiri (>= 1.12.0)
|
97
|
+
mail (2.8.1)
|
92
98
|
mini_mime (>= 0.1.1)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
99
|
+
net-imap
|
100
|
+
net-pop
|
101
|
+
net-smtp
|
102
|
+
marcel (1.0.4)
|
103
|
+
method_source (1.1.0)
|
104
|
+
mini_mime (1.1.5)
|
105
|
+
mini_portile2 (2.8.8)
|
106
|
+
minitest (5.25.5)
|
107
|
+
mongo (2.21.0)
|
108
|
+
bson (>= 4.14.1, < 6.0.0)
|
109
|
+
mongoid (9.0.6)
|
110
|
+
activemodel (>= 5.1, < 8.1, != 7.0.0)
|
111
|
+
concurrent-ruby (>= 1.0.5, < 2.0)
|
112
|
+
mongo (>= 2.18.0, < 3.0.0)
|
113
|
+
net-imap (0.5.6)
|
114
|
+
date
|
115
|
+
net-protocol
|
116
|
+
net-pop (0.1.2)
|
117
|
+
net-protocol
|
118
|
+
net-protocol (0.2.2)
|
119
|
+
timeout
|
120
|
+
net-smtp (0.5.1)
|
121
|
+
net-protocol
|
122
|
+
nio4r (2.7.4)
|
123
|
+
nokogiri (1.18.6)
|
106
124
|
mini_portile2 (~> 2.8.2)
|
107
125
|
racc (~> 1.4)
|
108
|
-
parallel (1.
|
109
|
-
parser (3.
|
126
|
+
parallel (1.26.3)
|
127
|
+
parser (3.3.7.3)
|
110
128
|
ast (~> 2.4.1)
|
111
|
-
|
129
|
+
racc
|
130
|
+
prism (1.4.0)
|
131
|
+
pry (0.14.2)
|
112
132
|
coderay (~> 1.1)
|
113
133
|
method_source (~> 1.0)
|
114
|
-
pry-byebug (3.
|
134
|
+
pry-byebug (3.10.1)
|
115
135
|
byebug (~> 11.0)
|
116
|
-
pry (
|
117
|
-
racc (1.8.
|
118
|
-
rack (2.2.
|
119
|
-
rack-test (
|
120
|
-
rack (>= 1.
|
121
|
-
rails (6.1.7.
|
122
|
-
actioncable (= 6.1.7.
|
123
|
-
actionmailbox (= 6.1.7.
|
124
|
-
actionmailer (= 6.1.7.
|
125
|
-
actionpack (= 6.1.7.
|
126
|
-
actiontext (= 6.1.7.
|
127
|
-
actionview (= 6.1.7.
|
128
|
-
activejob (= 6.1.7.
|
129
|
-
activemodel (= 6.1.7.
|
130
|
-
activerecord (= 6.1.7.
|
131
|
-
activestorage (= 6.1.7.
|
132
|
-
activesupport (= 6.1.7.
|
136
|
+
pry (>= 0.13, < 0.15)
|
137
|
+
racc (1.8.1)
|
138
|
+
rack (2.2.13)
|
139
|
+
rack-test (2.2.0)
|
140
|
+
rack (>= 1.3)
|
141
|
+
rails (6.1.7.10)
|
142
|
+
actioncable (= 6.1.7.10)
|
143
|
+
actionmailbox (= 6.1.7.10)
|
144
|
+
actionmailer (= 6.1.7.10)
|
145
|
+
actionpack (= 6.1.7.10)
|
146
|
+
actiontext (= 6.1.7.10)
|
147
|
+
actionview (= 6.1.7.10)
|
148
|
+
activejob (= 6.1.7.10)
|
149
|
+
activemodel (= 6.1.7.10)
|
150
|
+
activerecord (= 6.1.7.10)
|
151
|
+
activestorage (= 6.1.7.10)
|
152
|
+
activesupport (= 6.1.7.10)
|
133
153
|
bundler (>= 1.15.0)
|
134
|
-
railties (= 6.1.7.
|
154
|
+
railties (= 6.1.7.10)
|
135
155
|
sprockets-rails (>= 2.0.0)
|
136
|
-
rails-dom-testing (2.0
|
137
|
-
activesupport (>=
|
156
|
+
rails-dom-testing (2.2.0)
|
157
|
+
activesupport (>= 5.0.0)
|
158
|
+
minitest
|
138
159
|
nokogiri (>= 1.6)
|
139
|
-
rails-html-sanitizer (1.
|
140
|
-
loofah (~> 2.
|
141
|
-
|
142
|
-
|
143
|
-
|
160
|
+
rails-html-sanitizer (1.6.2)
|
161
|
+
loofah (~> 2.21)
|
162
|
+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
163
|
+
railties (6.1.7.10)
|
164
|
+
actionpack (= 6.1.7.10)
|
165
|
+
activesupport (= 6.1.7.10)
|
144
166
|
method_source
|
145
167
|
rake (>= 12.2)
|
146
168
|
thor (~> 1.0)
|
147
169
|
rainbow (3.1.1)
|
148
|
-
rake (13.
|
149
|
-
regexp_parser (2.
|
150
|
-
rexml (3.
|
151
|
-
|
152
|
-
|
153
|
-
rspec-
|
154
|
-
rspec-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
rspec-expectations (3.10.2)
|
170
|
+
rake (13.2.1)
|
171
|
+
regexp_parser (2.10.0)
|
172
|
+
rexml (3.4.1)
|
173
|
+
rspec (3.13.0)
|
174
|
+
rspec-core (~> 3.13.0)
|
175
|
+
rspec-expectations (~> 3.13.0)
|
176
|
+
rspec-mocks (~> 3.13.0)
|
177
|
+
rspec-core (3.13.3)
|
178
|
+
rspec-support (~> 3.13.0)
|
179
|
+
rspec-expectations (3.13.3)
|
159
180
|
diff-lcs (>= 1.2.0, < 2.0)
|
160
|
-
rspec-support (~> 3.
|
161
|
-
rspec-mocks (3.
|
181
|
+
rspec-support (~> 3.13.0)
|
182
|
+
rspec-mocks (3.13.2)
|
162
183
|
diff-lcs (>= 1.2.0, < 2.0)
|
163
|
-
rspec-support (~> 3.
|
164
|
-
rspec-support (3.
|
184
|
+
rspec-support (~> 3.13.0)
|
185
|
+
rspec-support (3.13.2)
|
165
186
|
rubocop (1.5.2)
|
166
187
|
parallel (~> 1.10)
|
167
188
|
parser (>= 2.7.1.5)
|
@@ -171,38 +192,39 @@ GEM
|
|
171
192
|
rubocop-ast (>= 1.2.0, < 2.0)
|
172
193
|
ruby-progressbar (~> 1.7)
|
173
194
|
unicode-display_width (>= 1.4.0, < 2.0)
|
174
|
-
rubocop-ast (1.
|
175
|
-
parser (>= 3.
|
195
|
+
rubocop-ast (1.43.0)
|
196
|
+
parser (>= 3.3.7.2)
|
197
|
+
prism (~> 1.4)
|
176
198
|
rubocop-performance (1.10.2)
|
177
199
|
rubocop (>= 0.90.0, < 2.0)
|
178
200
|
rubocop-ast (>= 0.4.0)
|
179
201
|
rubocop-rspec (2.4.0)
|
180
202
|
rubocop (~> 1.0)
|
181
203
|
rubocop-ast (>= 1.1.0)
|
182
|
-
ruby-progressbar (1.
|
183
|
-
ruby2_keywords (0.0.5)
|
204
|
+
ruby-progressbar (1.13.0)
|
184
205
|
simplecov (0.21.2)
|
185
206
|
docile (~> 1.1)
|
186
207
|
simplecov-html (~> 0.11)
|
187
208
|
simplecov_json_formatter (~> 0.1)
|
188
|
-
simplecov-html (0.
|
189
|
-
simplecov_json_formatter (0.1.
|
190
|
-
sprockets (4.
|
209
|
+
simplecov-html (0.13.1)
|
210
|
+
simplecov_json_formatter (0.1.4)
|
211
|
+
sprockets (4.2.1)
|
191
212
|
concurrent-ruby (~> 1.0)
|
192
|
-
rack (
|
193
|
-
sprockets-rails (3.
|
194
|
-
actionpack (>=
|
195
|
-
activesupport (>=
|
213
|
+
rack (>= 2.2.4, < 4)
|
214
|
+
sprockets-rails (3.5.2)
|
215
|
+
actionpack (>= 6.1)
|
216
|
+
activesupport (>= 6.1)
|
196
217
|
sprockets (>= 3.0.0)
|
197
|
-
|
198
|
-
|
218
|
+
thor (1.3.2)
|
219
|
+
timeout (0.4.3)
|
199
220
|
tzinfo (2.0.6)
|
200
221
|
concurrent-ruby (~> 1.0)
|
201
222
|
unicode-display_width (1.8.0)
|
202
|
-
websocket-driver (0.7.
|
223
|
+
websocket-driver (0.7.7)
|
224
|
+
base64
|
203
225
|
websocket-extensions (>= 0.1.0)
|
204
226
|
websocket-extensions (0.1.5)
|
205
|
-
zeitwerk (2.6.
|
227
|
+
zeitwerk (2.6.18)
|
206
228
|
|
207
229
|
PLATFORMS
|
208
230
|
ruby
|
@@ -25,7 +25,7 @@ class CommentDecorator < SimpleDelegator
|
|
25
25
|
end
|
26
26
|
```
|
27
27
|
|
28
|
-
In order to decorate object with
|
28
|
+
In order to decorate object with extra arguments, simply pass them to `.decorate` method. Like this:
|
29
29
|
|
30
30
|
```ruby
|
31
31
|
CommentDecorator.decorate(comment, current_user)
|
@@ -67,3 +67,33 @@ class UsersController < GraphqlRails::Controller
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
```
|
70
|
+
|
71
|
+
## Decorating with custom method
|
72
|
+
|
73
|
+
Sometimes building decorator instance is not that straight-forward and you need to use custom build strategy. In such cases you can pass `build_with: :DESIRED_CLASS_METHOD` option:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
class UserDecorator < SimpleDelegator
|
77
|
+
include GraphqlRails::Model
|
78
|
+
include GraphqlRails::Decorator
|
79
|
+
# ...
|
80
|
+
|
81
|
+
def self.custom_build(user)
|
82
|
+
user.admin? ? new(user, admin: true) : new(user)
|
83
|
+
end
|
84
|
+
|
85
|
+
def initialize(user, admin: false)
|
86
|
+
@user = user
|
87
|
+
@admin = admin
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class UsersController < GraphqlRails::Controller
|
92
|
+
action(:index).paginated.returns('[UserDecorator!]!')
|
93
|
+
|
94
|
+
def index
|
95
|
+
users = User.where(active: true)
|
96
|
+
UserDecorator.decorate(user, build_with: :custom_build)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
data/graphql_rails.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_dependency 'graphql', '2
|
23
|
+
spec.add_dependency 'graphql', '~> 2'
|
24
24
|
spec.add_dependency 'activesupport', '>= 4'
|
25
25
|
|
26
26
|
spec.add_development_dependency 'bundler', '~> 2'
|
@@ -4,9 +4,10 @@ module GraphqlRails
|
|
4
4
|
class Controller
|
5
5
|
# runs {before/around/after}_action controller hooks
|
6
6
|
class ActionHooksRunner
|
7
|
-
def initialize(action_name:, controller:)
|
7
|
+
def initialize(action_name:, controller:, graphql_request:)
|
8
8
|
@action_name = action_name
|
9
9
|
@controller = controller
|
10
|
+
@graphql_request = graphql_request
|
10
11
|
end
|
11
12
|
|
12
13
|
def call(&block)
|
@@ -19,7 +20,7 @@ module GraphqlRails
|
|
19
20
|
|
20
21
|
private
|
21
22
|
|
22
|
-
attr_reader :action_name, :controller
|
23
|
+
attr_reader :action_name, :controller, :graphql_request
|
23
24
|
|
24
25
|
def all_around_hooks
|
25
26
|
controller_configuration.action_hooks_for(:around, action_name)
|
@@ -30,6 +31,8 @@ module GraphqlRails
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def run_around_action_hooks(around_hooks = all_around_hooks, &block)
|
34
|
+
return if graphql_request.errors.any?
|
35
|
+
|
33
36
|
pending_around_hooks = around_hooks.clone
|
34
37
|
action_hook = pending_around_hooks.shift
|
35
38
|
|
@@ -41,6 +44,8 @@ module GraphqlRails
|
|
41
44
|
end
|
42
45
|
|
43
46
|
def execute_hook(action_hook, &block)
|
47
|
+
return if graphql_request.errors.any?
|
48
|
+
|
44
49
|
if action_hook.anonymous?
|
45
50
|
controller.instance_exec(controller, *block, &action_hook.action_proc)
|
46
51
|
else
|
@@ -89,7 +89,7 @@ module GraphqlRails
|
|
89
89
|
private
|
90
90
|
|
91
91
|
def call_with_rendering
|
92
|
-
hooks_runner = ActionHooksRunner.new(action_name: action_name, controller: self)
|
92
|
+
hooks_runner = ActionHooksRunner.new(action_name: action_name, controller: self, graphql_request: graphql_request)
|
93
93
|
response = hooks_runner.call { public_send(action_name) }
|
94
94
|
|
95
95
|
render response if graphql_request.no_object_to_return?
|
@@ -12,11 +12,12 @@ module GraphqlRails
|
|
12
12
|
defined?(Mongoid) && object.is_a?(Mongoid::Criteria)
|
13
13
|
end
|
14
14
|
|
15
|
-
def initialize(decorator:, relation:, decorator_args: [], decorator_kwargs: {})
|
15
|
+
def initialize(decorator:, relation:, decorator_args: [], decorator_kwargs: {}, build_with: :new)
|
16
16
|
@relation = relation
|
17
17
|
@decorator = decorator
|
18
18
|
@decorator_args = decorator_args
|
19
19
|
@decorator_kwargs = decorator_kwargs
|
20
|
+
@build_with = build_with
|
20
21
|
end
|
21
22
|
|
22
23
|
%i[where limit order group offset from select having all unscope].each do |method_name|
|
@@ -38,12 +39,12 @@ module GraphqlRails
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def to_a
|
41
|
-
@to_a ||= relation.to_a.map { |it|
|
42
|
+
@to_a ||= relation.to_a.map { |it| build_decorator(it, *decorator_args, **decorator_kwargs) }
|
42
43
|
end
|
43
44
|
|
44
45
|
private
|
45
46
|
|
46
|
-
attr_reader :relation, :decorator, :decorator_args, :decorator_kwargs
|
47
|
+
attr_reader :relation, :decorator, :decorator_args, :decorator_kwargs, :build_with
|
47
48
|
|
48
49
|
def decoratable_object_method(method_name, *args, **kwargs, &block)
|
49
50
|
object = relation.public_send(method_name, *args, **kwargs, &block)
|
@@ -54,12 +55,16 @@ module GraphqlRails
|
|
54
55
|
return object_or_list if object_or_list.blank?
|
55
56
|
|
56
57
|
if object_or_list.is_a?(Array)
|
57
|
-
object_or_list.map { |it|
|
58
|
+
object_or_list.map { |it| build_decorator(it, *decorator_args, **decorator_kwargs) }
|
58
59
|
else
|
59
|
-
|
60
|
+
build_decorator(object_or_list, *decorator_args, **decorator_kwargs)
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
64
|
+
def build_decorator(*args, **kwargs, &block)
|
65
|
+
decorator.public_send(build_with, *args, **kwargs, &block)
|
66
|
+
end
|
67
|
+
|
63
68
|
def decoratable_block_method(method_name, *args, **kwargs)
|
64
69
|
relation.public_send(method_name, *args, **kwargs) do |object, *other_args|
|
65
70
|
decorated_object = decorate(object)
|
@@ -71,7 +76,8 @@ module GraphqlRails
|
|
71
76
|
new_relation = relation.public_send(method_name, *args, **kwargs, &block)
|
72
77
|
self.class.new(
|
73
78
|
decorator: decorator, relation: new_relation,
|
74
|
-
decorator_args: decorator_args, decorator_kwargs: decorator_kwargs
|
79
|
+
decorator_args: decorator_args, decorator_kwargs: decorator_kwargs,
|
80
|
+
build_with: build_with
|
75
81
|
)
|
76
82
|
end
|
77
83
|
end
|
@@ -25,23 +25,27 @@ module GraphqlRails
|
|
25
25
|
extend ActiveSupport::Concern
|
26
26
|
|
27
27
|
class_methods do
|
28
|
-
def decorate(object, *args, **kwargs)
|
28
|
+
def decorate(object, *args, build_with: :new, **kwargs)
|
29
29
|
if Decorator::RelationDecorator.decorates?(object)
|
30
|
-
decorate_with_relation_decorator(object, args, kwargs)
|
30
|
+
decorate_with_relation_decorator(object, args, kwargs, build_with: build_with)
|
31
31
|
elsif object.nil?
|
32
32
|
nil
|
33
33
|
elsif object.is_a?(Array)
|
34
|
-
object.map { |item|
|
34
|
+
object.map { |item| public_send(build_with, item, *args, **kwargs) }
|
35
35
|
else
|
36
|
-
|
36
|
+
public_send(build_with, object, *args, **kwargs)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
41
41
|
|
42
|
-
def decorate_with_relation_decorator(object, args, kwargs)
|
42
|
+
def decorate_with_relation_decorator(object, args, kwargs, build_with:)
|
43
43
|
Decorator::RelationDecorator.new(
|
44
|
-
relation: object,
|
44
|
+
relation: object,
|
45
|
+
decorator: self,
|
46
|
+
decorator_args: args,
|
47
|
+
decorator_kwargs: kwargs,
|
48
|
+
build_with: build_with
|
45
49
|
)
|
46
50
|
end
|
47
51
|
end
|
@@ -6,6 +6,7 @@ module GraphqlRails
|
|
6
6
|
class AddFieldsToGraphqlType
|
7
7
|
require 'graphql_rails/concerns/service'
|
8
8
|
require 'graphql_rails/model/call_graphql_model_method'
|
9
|
+
require 'graphql_rails/model/direct_field_resolver'
|
9
10
|
|
10
11
|
include ::GraphqlRails::Service
|
11
12
|
|
@@ -31,7 +32,7 @@ module GraphqlRails
|
|
31
32
|
end
|
32
33
|
|
33
34
|
define_method(attribute.field_name) do |**kwargs|
|
34
|
-
|
35
|
+
DirectFieldResolver.call(
|
35
36
|
model: object,
|
36
37
|
attribute_config: attribute,
|
37
38
|
method_keyword_arguments: kwargs,
|
@@ -10,14 +10,24 @@ module GraphqlRails
|
|
10
10
|
|
11
11
|
PAGINATION_KEYS = %i[before after first last].freeze
|
12
12
|
|
13
|
-
|
13
|
+
@instance_cache = {}
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_reader :instance_cache
|
17
|
+
|
18
|
+
def call(*_args, **kwargs)
|
19
|
+
cache_key = kwargs[:attribute_config].object_id
|
20
|
+
@instance_cache[cache_key] ||= new
|
21
|
+
@instance_cache[cache_key].call_with_args(**kwargs)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def call_with_args(model:, method_keyword_arguments:, graphql_context:, attribute_config:)
|
14
26
|
@model = model
|
15
27
|
@method_keyword_arguments = method_keyword_arguments
|
16
28
|
@graphql_context = graphql_context
|
17
29
|
@attribute_config = attribute_config
|
18
|
-
end
|
19
30
|
|
20
|
-
def call
|
21
31
|
with_graphql_context do
|
22
32
|
run_method
|
23
33
|
end
|
@@ -59,7 +69,9 @@ module GraphqlRails
|
|
59
69
|
def custom_keyword_arguments
|
60
70
|
return method_keyword_arguments unless paginated?
|
61
71
|
|
62
|
-
method_keyword_arguments.
|
72
|
+
method_keyword_arguments.each_with_object({}) do |(key, value), result|
|
73
|
+
result[key] = value unless PAGINATION_KEYS.include?(key)
|
74
|
+
end
|
63
75
|
end
|
64
76
|
|
65
77
|
def with_graphql_context
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlRails
|
4
|
+
module Model
|
5
|
+
# Takes shortcuts for simple cases to minimize allocations
|
6
|
+
class DirectFieldResolver
|
7
|
+
class << self
|
8
|
+
def call(model:, attribute_config:, method_keyword_arguments:, graphql_context:)
|
9
|
+
property = attribute_config.property
|
10
|
+
|
11
|
+
if method_keyword_arguments.empty? && !attribute_config.paginated?
|
12
|
+
return simple_resolver(model: model, graphql_context: graphql_context, property: property)
|
13
|
+
end
|
14
|
+
|
15
|
+
CallGraphqlModelMethod.call(
|
16
|
+
model: model,
|
17
|
+
attribute_config: attribute_config,
|
18
|
+
method_keyword_arguments: method_keyword_arguments,
|
19
|
+
graphql_context: graphql_context
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def simple_resolver(model:, graphql_context:, property:)
|
24
|
+
return model.send(property) unless model.respond_to?(:with_graphql_context)
|
25
|
+
|
26
|
+
model.with_graphql_context(graphql_context) { model.send(property) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -32,6 +32,8 @@ module GraphqlRails
|
|
32
32
|
# rubocop:disable Metrics/MethodLength
|
33
33
|
def define_schema_class(query_type, mutation_type, subscription_type, raw)
|
34
34
|
Class.new(GraphQL::Schema) do
|
35
|
+
use GraphQL::Schema::Visibility
|
36
|
+
|
35
37
|
connections.add(
|
36
38
|
GraphqlRails::Decorator::RelationDecorator,
|
37
39
|
GraphQL::Pagination::ActiveRecordRelationConnection
|
data/lib/graphql_rails/router.rb
CHANGED
@@ -12,7 +12,7 @@ module GraphqlRails
|
|
12
12
|
# graphql router that mimics Rails.application.routes
|
13
13
|
class Router
|
14
14
|
RAW_ACTION_NAMES = %i[
|
15
|
-
use rescue_from query_analyzer instrument cursor_encoder default_max_page_size
|
15
|
+
use rescue_from query_analyzer instrument cursor_encoder default_max_page_size tracer trace_with
|
16
16
|
].freeze
|
17
17
|
|
18
18
|
def self.draw(&block)
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Povilas Jurčys
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2
|
19
|
+
version: '2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2
|
26
|
+
version: '2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,7 +122,7 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '6'
|
125
|
-
description:
|
125
|
+
description:
|
126
126
|
email:
|
127
127
|
- po.jurcys@gmail.com
|
128
128
|
executables: []
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- lib/graphql_rails/model/call_graphql_model_method.rb
|
208
208
|
- lib/graphql_rails/model/configurable.rb
|
209
209
|
- lib/graphql_rails/model/configuration.rb
|
210
|
+
- lib/graphql_rails/model/direct_field_resolver.rb
|
210
211
|
- lib/graphql_rails/model/find_or_build_graphql_input_type.rb
|
211
212
|
- lib/graphql_rails/model/find_or_build_graphql_type.rb
|
212
213
|
- lib/graphql_rails/model/find_or_build_graphql_type_class.rb
|
@@ -236,7 +237,7 @@ homepage: https://github.com/samesystem/graphql_rails
|
|
236
237
|
licenses:
|
237
238
|
- MIT
|
238
239
|
metadata: {}
|
239
|
-
post_install_message:
|
240
|
+
post_install_message:
|
240
241
|
rdoc_options: []
|
241
242
|
require_paths:
|
242
243
|
- lib
|
@@ -252,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
252
253
|
version: '0'
|
253
254
|
requirements: []
|
254
255
|
rubygems_version: 3.3.7
|
255
|
-
signing_key:
|
256
|
+
signing_key:
|
256
257
|
specification_version: 4
|
257
258
|
summary: Rails style structure for GraphQL API.
|
258
259
|
test_files: []
|