graphql_preload_queries 0.1.0 → 0.3.1
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/CHANGELOG.md +20 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +4 -1
- data/README.md +62 -61
- data/config/initializers/add_mutation_helper.rb +32 -0
- data/config/initializers/add_preload_field.rb +26 -18
- data/config/initializers/add_query_helper.rb +34 -0
- data/config/initializers/patch_continue_value.rb +18 -0
- data/lib/graphql_preload_queries.rb +4 -0
- data/lib/graphql_preload_queries/extensions/preload.rb +27 -24
- data/lib/graphql_preload_queries/version.rb +1 -1
- metadata +6 -4
- data/config/initializers/add_mutation_resolver.rb +0 -26
- data/config/initializers/add_query_resolver.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89226168aa382eb59c56754b96a4eaa64c51c5f06fc6fd8d831b7795d84adf0e
|
4
|
+
data.tar.gz: b29ec85aa619a1f7412944d6f50388f68c9b196cc5e8607bc22fd163f3a64ed1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42df9aacf5b59d341fc5498a61890a1ecd5c76713179c94b81696084af7d9d4f52abdd105c26a04775aa6b8199f86398841bf230127df711ffceef386752f7f9
|
7
|
+
data.tar.gz: cded97146bc935064f7dcaa94034deffd06adf1b6cf3c2daaacf746fb11eef542b261debd505ccb8963ec3b67f60cf7386d4829aeaa13feaed024786fa7ec04e
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
## 0.3.1 (22-01-2021)
|
2
|
+
- feat: auto camelize key for queries and mutations
|
3
|
+
|
4
|
+
## 0.3 (22-01-2021)
|
5
|
+
- feat: add debug mode
|
6
|
+
```GraphqlPreloadQueries::DEBUG = true```
|
7
|
+
- fix: detect the correct Query Result Type
|
8
|
+
|
9
|
+
## 0.2.2 (21-01-2021)
|
10
|
+
- Fix: Fix deep recursive stack error
|
11
|
+
|
12
|
+
## 0.2.1 (21-01-2021)
|
13
|
+
- fix: add default preload to key
|
14
|
+
- fix: fix invalid key when deep preloading
|
15
|
+
|
16
|
+
## 0.2.0 (02-12-2020)
|
17
|
+
- Refactor: Preload associations when iterating activeRecord::Relation
|
18
|
+
|
19
|
+
## 0.1.0 (10-11-2020
|
20
|
+
- Add rails query preload support for queries, mutations and gql object types.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
graphql_preload_queries (0.1
|
4
|
+
graphql_preload_queries (0.3.1)
|
5
5
|
graphql
|
6
6
|
rails
|
7
7
|
|
@@ -190,5 +190,8 @@ DEPENDENCIES
|
|
190
190
|
rubocop-rspec
|
191
191
|
sqlite3
|
192
192
|
|
193
|
+
RUBY VERSION
|
194
|
+
ruby 2.6.5p114
|
195
|
+
|
193
196
|
BUNDLED WITH
|
194
197
|
2.1.4
|
data/README.md
CHANGED
@@ -1,77 +1,72 @@
|
|
1
|
-
# GraphqlPreloadQueries
|
2
|
-
This gem helps to define all
|
1
|
+
# GraphqlPreloadQueries
|
2
|
+
This gem helps you to define all nested preloads to be added when required for graphql data results and avoid the common problem "N+1 Queries".
|
3
3
|
|
4
4
|
## Usage
|
5
|
-
*
|
5
|
+
* Object Type
|
6
6
|
```ruby
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
class UserType < Types::BaseObject
|
8
|
+
add_preload 'parents|allParents', { preload: :parents, friends: :friends, parents: :parents }
|
9
|
+
add_preload :friends, { parents: { preload: :parents, parents: :parents, friends: :friends } }
|
10
|
+
|
11
|
+
field :id, Int, null: true
|
12
|
+
field :name, String, null: true
|
13
|
+
field :friends, [Types::UserType], null: false
|
14
|
+
field :parents, [Types::UserType], null: false
|
15
|
+
end
|
11
16
|
```
|
12
|
-
|
13
|
-
*
|
14
|
-
|
17
|
+
Examples:
|
18
|
+
* ```add_preload(:friends)```
|
19
|
+
```:friends``` association will be preloaded if query includes ```friends```, like: ```user(id: 10) { friends { ... } }```
|
15
20
|
|
16
|
-
|
21
|
+
* ```add_preload(:allFriends, :friends)```
|
22
|
+
```:friends``` association will be preloaded if query includes ```allFriends```, like: ```user(id: 10) { allFriends { ... } }```
|
23
|
+
|
24
|
+
* ```add_preload(:allFriends, { preload: :friends, parents: :parents })```
|
25
|
+
```:preload``` key can be used to indicate the association name when defining nested preloads, like: ```user(id: 10) { allFriends { id parents { ... } } }```
|
26
|
+
|
27
|
+
* ```add_preload(:friends, { allParents: :parents })```
|
28
|
+
(Nested 1 lvl preloading) ```friends: :parents``` association will be preloaded if query includes ```allParents```, like: ```user(id: 10) { friends { allParents { ... } } }```
|
29
|
+
|
30
|
+
* ```add_preload(:friends, { allParents: { preload: :parents, friends: :friends } })```
|
31
|
+
(Nested 2 levels preloading) ```friends: { parents: :friends }``` association will be preloaded if query includes ```friends``` inside ```parents```, like: ```user(id: 10) { friends { allParents { { friends { ... } } } } }```
|
32
|
+
|
33
|
+
* ```add_preload('friends|allFriends', :friends)```
|
34
|
+
(Multiple gql queries) ```:friends``` association will be preloaded if query includes ```friends``` or ```allFriends```, like: ```user(id: 10) { friends { ... } }``` OR ```user(id: 10) { allFriends { ... } }```
|
35
|
+
|
36
|
+
* ```add_preload('ignoredFriends', 'ignored_friends.user')```
|
37
|
+
(Deep preloading) ```{ ignored_friends: :user }``` association will be preloaded if query includes ```inogredFriends```, like: ```user(id: 10) { ignoredFriends { ... } }```
|
38
|
+
|
39
|
+
* Preloads in query results
|
17
40
|
```ruby
|
18
|
-
#
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
41
|
+
# queries/users.rb
|
42
|
+
def user(id:)
|
43
|
+
# includes all preloads defined in user type
|
44
|
+
# Sample: user(id: 10){ friends { id } }
|
45
|
+
# :friends will be preloaded inside "user" sql query
|
46
|
+
user = include_gql_preloads(:user, User.where(id: id))
|
47
|
+
|
48
|
+
# does not include user type preloads (only sub query preloads will be applied)
|
49
|
+
# Sample: user(id: 10){ friends { id parents { ... } } }
|
50
|
+
# Only :parents will be preloaded inside "friends" sql query
|
51
|
+
user = User.find(id)
|
23
52
|
end
|
24
53
|
```
|
25
|
-
|
26
|
-
* The result articles query includes "allComments", then ```:comments``` will automatically be preloaded
|
27
|
-
* The result articles query does not include "allComments", then ```:comments``` is not preloaded
|
54
|
+
- include_gql_preloads: Will preload all preloads configured in UserType based on the gql query.
|
28
55
|
|
29
|
-
* Preloads in
|
56
|
+
* Preloads in mutation results
|
30
57
|
```ruby
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
58
|
+
# mutations/users/disable.rb
|
59
|
+
#...
|
60
|
+
field :users, [Types::UserType], null: true
|
61
|
+
def resolve(ids:)
|
62
|
+
affected_users = User.where(id: ids)
|
63
|
+
affected_users = include_gql_preloads(:users, affected_users)
|
64
|
+
puts affected_users.first&.friends # will print preloaded friends data
|
65
|
+
{ users: affected_users }
|
36
66
|
end
|
37
67
|
```
|
38
|
-
|
39
|
-
* The query includes ```owner``` inside ```allComments```, then ```:author``` will automatically be preloaded inside "allComments" query
|
40
|
-
* The query does not include ```owner```, then ```:author``` is not preloaded
|
41
|
-
This field is exactly the same as the graphql field, except that this field expects for "preload" setting which contains all configurations for preloading
|
42
|
-
|
43
|
-
Complex preload settings
|
44
|
-
```ruby
|
45
|
-
# category query
|
46
|
-
{
|
47
|
-
'posts' =>
|
48
|
-
[:posts, # :posts preload key will be used when: { posts { id ... } }
|
49
|
-
{
|
50
|
-
'authors|allAuthors' => [:author, { # :author key will be used when: { posts { allAuthors { id ... } } }
|
51
|
-
address: :address # :address key will be used when: { posts { allAuthors { address { id ... } } } }
|
52
|
-
}],
|
53
|
-
history: :versions # :versions key will be used when: { posts { history { ... } } }
|
54
|
-
}
|
55
|
-
],
|
56
|
-
'disabledPosts' => ['category_disabled_posts.post', { # :category_disabled_posts.post key will be used when: { disabledPosts { ... } }
|
57
|
-
authors: :authors # :authors key will be used when: { disabledPosts { authors { ... } } }
|
58
|
-
}]
|
59
|
-
}
|
60
|
-
```
|
61
|
-
* ```authors|allAuthors``` means that the preload will be added if "authors" or "allAuthors" is present in the query
|
62
|
-
* ```category_disabled_posts.post``` means an inner preload, sample: ```posts.preload({ category_disabled_posts: :post })```
|
63
|
-
|
64
|
-
### Important:
|
65
|
-
Is needed to omit "extra" params auto provided by Graphql when using custom resolver (only in case not using params), sample:
|
66
|
-
```ruby
|
67
|
-
# types/post_type.rb
|
68
|
-
preload_field :allComments, [Types::CommentType], preload: { owner: :author }, null: false
|
69
|
-
def allComments(_omit_gql_params) # custom method resolver that omits non used params
|
70
|
-
object.allComments
|
71
|
-
end
|
72
|
-
```
|
68
|
+
- include_gql_preloads: Will preload all preloads configured in UserType based on the gql query.
|
73
69
|
|
74
|
-
|
75
70
|
## Installation
|
76
71
|
Add this line to your application's Gemfile:
|
77
72
|
|
@@ -89,6 +84,12 @@ Or install it yourself as:
|
|
89
84
|
$ gem install graphql_preload_queries
|
90
85
|
```
|
91
86
|
|
87
|
+
For debugging mode:
|
88
|
+
```
|
89
|
+
# config/initializers/gql_preload.rb
|
90
|
+
GraphqlPreloadQueries::DEBUG = true
|
91
|
+
```
|
92
|
+
|
92
93
|
## Contributing
|
93
94
|
Bug reports and pull requests are welcome on GitHub at https://github.com/owen2345/graphql_preload_queries. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
94
95
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# preload resolver for mutations
|
4
|
+
Rails.application.config.to_prepare do
|
5
|
+
GraphQL::Schema::Mutation.class_eval do
|
6
|
+
# TODO: auto recover type_klass using result key
|
7
|
+
# Add corresponding preloads to mutation results
|
8
|
+
# @param gql_result_key (String | Sym)
|
9
|
+
# @param collection (ActiveCollection)
|
10
|
+
# @param type_klass (GQL TypeClass)
|
11
|
+
def include_gql_preloads(gql_result_key, collection, type_klass = nil)
|
12
|
+
gql_result_key = GraphQL::Schema::Member::BuildType.camelize(gql_result_key.to_s)
|
13
|
+
type_klass ||= preload_type_klass(gql_result_key.to_s)
|
14
|
+
klass = GraphqlPreloadQueries::Extensions::Preload
|
15
|
+
ast_node = preload_find_node(gql_result_key)
|
16
|
+
klass.preload_associations(collection, ast_node, type_klass)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def preload_find_node(key)
|
22
|
+
main_node = context.query.document.definitions.first.selections.first
|
23
|
+
main_node.selections.find { |node_i| node_i.name == key.to_s }
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param result_key: String
|
27
|
+
def preload_type_klass(result_key)
|
28
|
+
res = self.class.fields[result_key].instance_variable_get(:@return_type_expr)
|
29
|
+
res.is_a?(Array) ? res.first : res
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -3,26 +3,34 @@
|
|
3
3
|
require 'graphql_preload_queries/extensions/preload'
|
4
4
|
|
5
5
|
Rails.application.config.to_prepare do
|
6
|
-
# Custom preload field for Object types
|
7
6
|
Types::BaseObject.class_eval do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# ==> <cat1>.preload(posts: :author) // if author and posts are in query
|
13
|
-
# ==> <cat1>.preload(:posts) // if only author is in the query
|
14
|
-
# ==> <cat1>.preload() // if both of them are not in the query
|
15
|
-
# TODO: ability to merge extensions + extras
|
16
|
-
def self.preload_field(key, type, settings = {})
|
17
|
-
klass = GraphqlPreloadQueries::Extensions::Preload
|
18
|
-
custom_attrs = {
|
19
|
-
extras: [:ast_node],
|
20
|
-
extensions: [klass => settings.delete(:preload)]
|
21
|
-
}
|
22
|
-
field key, type, settings.merge(custom_attrs)
|
7
|
+
class << self
|
8
|
+
def preloads
|
9
|
+
@preloads ||= {}
|
10
|
+
end
|
23
11
|
|
24
|
-
#
|
25
|
-
|
12
|
+
# @param key (Symbol|String)
|
13
|
+
# @param preload (Symbol|String or Symbol|String|Hash)
|
14
|
+
# @Sample:
|
15
|
+
## key argument supports for multiple query names
|
16
|
+
# add_preload('users|allUsers', :users)
|
17
|
+
## preload argument indicates the association name to be preloaded
|
18
|
+
# add_preload(:allUsers, :users)
|
19
|
+
## preload argument supports for nested associations
|
20
|
+
# add_preload(:inactiveUsers, 'inactivated_users.user')
|
21
|
+
## "preload" key should be specified to indicate the association name
|
22
|
+
# add_preload(:allUsers, { preload: :users, 'allComments|comments' => :comments } })
|
23
|
+
## preload key can be omitted to use the same name as the key
|
24
|
+
# add_preload(:users, { 'allComments|comments' => :comments } })
|
25
|
+
def add_preload(key, preload = key)
|
26
|
+
preload ||= key
|
27
|
+
raise('Invalid preload query key') if [String, Symbol].exclude?(key.class)
|
28
|
+
raise('Invalid preload preload key') if [String, Symbol, Hash].exclude?(preload.class)
|
29
|
+
|
30
|
+
preload[:preload] ||= key if preload.is_a?(Hash)
|
31
|
+
key = GraphQL::Schema::Member::BuildType.camelize(key.to_s)
|
32
|
+
preloads[key] = preload
|
33
|
+
end
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# preload resolver for queries
|
4
|
+
Rails.application.config.to_prepare do
|
5
|
+
Types::QueryType.class_eval do
|
6
|
+
# TODO: auto recover type_klass using result key
|
7
|
+
# Add corresponding preloads to query results
|
8
|
+
# Note: key is automatically calculated based on method name
|
9
|
+
# @param gql_result_key (String | Sym)
|
10
|
+
# @param collection (ActiveCollection)
|
11
|
+
# @param type_klass (GQL TypeClass, default: calculates using return type)
|
12
|
+
def include_gql_preloads(gql_result_key, collection, type_klass = nil)
|
13
|
+
gql_result_key = GraphQL::Schema::Member::BuildType.camelize(gql_result_key.to_s)
|
14
|
+
type_klass ||= preload_type_klass(gql_result_key.to_s)
|
15
|
+
klass = GraphqlPreloadQueries::Extensions::Preload
|
16
|
+
ast_node = preload_find_node(gql_result_key)
|
17
|
+
klass.preload_associations(collection, ast_node, type_klass)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# @param key: Symbol
|
23
|
+
def preload_find_node(key)
|
24
|
+
main_node = context.query.document.definitions.first
|
25
|
+
main_node.selections.find { |node_i| node_i.name == key.to_s }
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param result_key: String
|
29
|
+
def preload_type_klass(result_key)
|
30
|
+
res = self.class.fields[result_key].instance_variable_get(:@return_type_expr)
|
31
|
+
res.is_a?(Array) ? res.first : res
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'graphql/execution/interpreter/runtime'
|
4
|
+
module GraphqlPreloadQueries::PatchContinueValue # rubocop:disable Style/ClassAndModuleChildren:
|
5
|
+
# gql args: path, value, parent_type, field, is_non_null, ast_node
|
6
|
+
def continue_value(*args)
|
7
|
+
value = args[1]
|
8
|
+
ast_node = args[5]
|
9
|
+
field = args[3]
|
10
|
+
type_klass = Array(field.instance_variable_get(:@return_type_expr))[0]
|
11
|
+
is_active_record = value.is_a?(ActiveRecord::Relation)
|
12
|
+
return super if !is_active_record || value.loaded? || !type_klass.respond_to?(:preloads)
|
13
|
+
|
14
|
+
klass = GraphqlPreloadQueries::Extensions::Preload
|
15
|
+
klass.preload_associations(value, ast_node, type_klass)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
GraphQL::Execution::Interpreter::Runtime.prepend GraphqlPreloadQueries::PatchContinueValue
|
@@ -5,51 +5,54 @@
|
|
5
5
|
module GraphqlPreloadQueries
|
6
6
|
module Extensions
|
7
7
|
class Preload < GraphQL::Schema::FieldExtension
|
8
|
-
# extension to add eager loading when a field was already processed
|
9
|
-
def resolve(object:, arguments:, **_rest)
|
10
|
-
klass = GraphqlPreloadQueries::Extensions::Preload
|
11
|
-
res = yield(object, arguments)
|
12
|
-
return res unless res
|
13
|
-
|
14
|
-
klass.resolve_preloads(res, arguments[:ast_node], (options || {}))
|
15
|
-
end
|
16
|
-
|
17
8
|
class << self
|
18
9
|
# Add all the corresponding preloads to the collection
|
19
|
-
# @param
|
20
|
-
# @
|
21
|
-
#
|
22
|
-
|
23
|
-
|
10
|
+
# @param value (ActiveCollection)
|
11
|
+
# @param @node (GqlNode)
|
12
|
+
# @param @type_klass (GqlTypeKlass)
|
13
|
+
# @return @data with necessary preloads
|
14
|
+
def preload_associations(value, node, type_klass)
|
15
|
+
preloads = filter_preloads(node, type_klass.preloads || {})
|
16
|
+
log_info = { type_klass: type_klass, preloads: preloads, configured: type_klass.preloads }
|
17
|
+
GraphqlPreloadQueries.log("Preloading: #{log_info}")
|
18
|
+
apply_preloads(value, preloads)
|
24
19
|
end
|
25
20
|
|
21
|
+
private
|
22
|
+
|
26
23
|
def apply_preloads(collection, preloads)
|
27
24
|
collection.eager_load(preloads)
|
28
25
|
end
|
29
26
|
|
30
27
|
# find all configured preloads inside a node
|
31
28
|
def filter_preloads(node, preload_conf, root = nested_hash)
|
29
|
+
return root unless node
|
30
|
+
|
32
31
|
preload_conf.map do |key, sub_preload_conf|
|
33
32
|
filter_preload(node, key, sub_preload_conf, root)
|
34
33
|
end
|
35
34
|
root
|
36
35
|
end
|
37
36
|
|
38
|
-
private
|
39
|
-
|
40
37
|
# find preloads under a specific key
|
41
38
|
def filter_preload(node, key, preload_conf, root)
|
42
|
-
sub_node = node
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
multiple_preload = preload_conf.is_a?(Array)
|
39
|
+
sub_node = sub_node(node, key)
|
40
|
+
multiple_preload = preload_conf.is_a?(Hash)
|
47
41
|
return unless sub_node
|
48
|
-
return add_preload_key(root, preload_conf,
|
42
|
+
return add_preload_key(root, preload_conf, {}) unless multiple_preload
|
49
43
|
|
50
44
|
child_root = nested_hash
|
51
|
-
|
52
|
-
|
45
|
+
association_name = preload_conf[:preload] || key.to_s.underscore
|
46
|
+
filter_preloads(sub_node, preload_conf, child_root)
|
47
|
+
add_preload_key(root, association_name, child_root.presence || {})
|
48
|
+
end
|
49
|
+
|
50
|
+
def sub_node(node, key)
|
51
|
+
is_relay_node = %w[nodes edges].include?(node.selections.first.name)
|
52
|
+
node = node.selections.first if is_relay_node
|
53
|
+
node.selections.find do |node_i|
|
54
|
+
key.to_s.split('|').include?(node_i.name.to_s)
|
55
|
+
end
|
53
56
|
end
|
54
57
|
|
55
58
|
# parse nested preload key and add it to the tree
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_preload_queries
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- owen2345
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -120,15 +120,17 @@ files:
|
|
120
120
|
- ".gitignore"
|
121
121
|
- ".rspec"
|
122
122
|
- ".rubocop.yml"
|
123
|
+
- CHANGELOG.md
|
123
124
|
- Gemfile
|
124
125
|
- Gemfile.lock
|
125
126
|
- MIT-LICENSE
|
126
127
|
- README.md
|
127
128
|
- Rakefile
|
128
129
|
- bin/rails
|
129
|
-
- config/initializers/
|
130
|
+
- config/initializers/add_mutation_helper.rb
|
130
131
|
- config/initializers/add_preload_field.rb
|
131
|
-
- config/initializers/
|
132
|
+
- config/initializers/add_query_helper.rb
|
133
|
+
- config/initializers/patch_continue_value.rb
|
132
134
|
- gemfiles/Gemfile_4
|
133
135
|
- gemfiles/Gemfile_5
|
134
136
|
- gemfiles/Gemfile_6
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# preload resolver for mutations
|
4
|
-
Rails.application.config.to_prepare do
|
5
|
-
GraphQL::Schema::Mutation.class_eval do
|
6
|
-
# Add corresponding preloads to mutation results
|
7
|
-
# @param key (sym) key of the query
|
8
|
-
# @param data (ActiveCollection)
|
9
|
-
# @param preload_config (Same as Field: field[:preload])
|
10
|
-
def resolve_preloads(key, data, preload_config)
|
11
|
-
node = find_node(key)
|
12
|
-
return data unless node
|
13
|
-
|
14
|
-
# relay support (TODO: add support to skip when not using relay)
|
15
|
-
node = node.selections.first if %w[nodes edges].include?(node.selections.first.name)
|
16
|
-
GraphqlPreloadQueries::Extensions::Preload.resolve_preloads(data, node, preload_config)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def find_node(key)
|
22
|
-
main_node = context.query.document.definitions.first.selections.first
|
23
|
-
main_node.selections.find { |node_i| node_i.name == key.to_s }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# preload resolver for queries
|
4
|
-
Rails.application.config.to_prepare do
|
5
|
-
Types::QueryType.class_eval do
|
6
|
-
# Add corresponding preloads to query results
|
7
|
-
# Note: key is automatically calculated based on method name
|
8
|
-
# @param data (ActiveCollection)
|
9
|
-
# @param preload_config (Same as Field: field[:preload])
|
10
|
-
def resolve_preloads(data, preload_config)
|
11
|
-
node = find_node(caller[0][/`.*'/][1..-2])
|
12
|
-
return data unless node
|
13
|
-
|
14
|
-
# relay support (TODO: add support to skip when not using relay)
|
15
|
-
node = node.selections.first if %w[nodes edges].include?(node.selections.first.name)
|
16
|
-
GraphqlPreloadQueries::Extensions::Preload.resolve_preloads(data, node, preload_config)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def find_node(key)
|
22
|
-
main_node = context.query.document.definitions.first
|
23
|
-
main_node.selections.find { |node_i| node_i.name == key.to_s }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|