graphql-eager_load 0.2.2
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 +7 -0
- data/.github/workflows/test.yml +34 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +6 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +202 -0
- data/LICENSE.txt +1 -0
- data/README.md +55 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config.ru +9 -0
- data/graphql-eager-load.gemspec +31 -0
- data/lib/graphql/eager_load.rb +8 -0
- data/lib/graphql/eager_load/builder.rb +109 -0
- data/lib/graphql/eager_load/resolver.rb +30 -0
- data/lib/graphql/eager_load/version.rb +7 -0
- metadata +64 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a51028f140032e8b436a06fa19ad0d5fe1ad5e16ac2f0881acabaa3738e287bc
|
|
4
|
+
data.tar.gz: cb1cf7507e675e881699e679d6a9f248ce1a7bcd0697e6f1d90020325b1482cd
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 29058b322738f586de82e832722625fa5c1c09ce7716cc2377cfe30b1a7e0dbf21655221d9977135f683938241a1b2141632d6ded7affe4dd86e82c1db1c6ee0
|
|
7
|
+
data.tar.gz: 1ca0c090115b58c18bd01826c20f93c6019e53bba375ff970b3b8406223b16c2b2b4a3b57b1314620fbc099d692784924bc154dfd75a3f114c265cdc294b758a
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
on: [push]
|
|
2
|
+
|
|
3
|
+
name: Test
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
run:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
|
|
9
|
+
steps:
|
|
10
|
+
- name: Checkout
|
|
11
|
+
uses: actions/checkout@master
|
|
12
|
+
|
|
13
|
+
- name: Set up Ruby
|
|
14
|
+
uses: actions/setup-ruby@v1
|
|
15
|
+
with:
|
|
16
|
+
ruby-version: '2.7.x'
|
|
17
|
+
bundler-cache: true
|
|
18
|
+
|
|
19
|
+
- name: Cache bundled gems
|
|
20
|
+
uses: actions/cache@v2
|
|
21
|
+
with:
|
|
22
|
+
path: vendor/bundle
|
|
23
|
+
key: ${{ runner.os }}-gems-${{ hashFiles('Gemfile.lock') }}
|
|
24
|
+
restore-keys: |
|
|
25
|
+
${{ runner.os }}-gems-
|
|
26
|
+
|
|
27
|
+
- name: Install Ruby gems
|
|
28
|
+
run: |
|
|
29
|
+
bundle config path vendor/bundle
|
|
30
|
+
bundle install
|
|
31
|
+
|
|
32
|
+
- name: Run Rspec
|
|
33
|
+
run: |
|
|
34
|
+
bundle exec rspec
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
|
+
|
|
5
|
+
# Specify your gem's dependencies in graphql-eager-load.gemspec
|
|
6
|
+
gemspec
|
|
7
|
+
|
|
8
|
+
gem 'graphql'
|
|
9
|
+
|
|
10
|
+
group :test, :development do
|
|
11
|
+
gem 'combustion'
|
|
12
|
+
gem 'rails'
|
|
13
|
+
gem 'rake'
|
|
14
|
+
gem 'rubocop'
|
|
15
|
+
gem 'rubocop-performance'
|
|
16
|
+
gem 'rubocop-rspec'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
group :test do
|
|
20
|
+
gem 'rspec'
|
|
21
|
+
gem 'rspec-rails'
|
|
22
|
+
gem 'sqlite3'
|
|
23
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
graphql-eager_load (0.2.2)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
actioncable (6.0.3.2)
|
|
10
|
+
actionpack (= 6.0.3.2)
|
|
11
|
+
nio4r (~> 2.0)
|
|
12
|
+
websocket-driver (>= 0.6.1)
|
|
13
|
+
actionmailbox (6.0.3.2)
|
|
14
|
+
actionpack (= 6.0.3.2)
|
|
15
|
+
activejob (= 6.0.3.2)
|
|
16
|
+
activerecord (= 6.0.3.2)
|
|
17
|
+
activestorage (= 6.0.3.2)
|
|
18
|
+
activesupport (= 6.0.3.2)
|
|
19
|
+
mail (>= 2.7.1)
|
|
20
|
+
actionmailer (6.0.3.2)
|
|
21
|
+
actionpack (= 6.0.3.2)
|
|
22
|
+
actionview (= 6.0.3.2)
|
|
23
|
+
activejob (= 6.0.3.2)
|
|
24
|
+
mail (~> 2.5, >= 2.5.4)
|
|
25
|
+
rails-dom-testing (~> 2.0)
|
|
26
|
+
actionpack (6.0.3.2)
|
|
27
|
+
actionview (= 6.0.3.2)
|
|
28
|
+
activesupport (= 6.0.3.2)
|
|
29
|
+
rack (~> 2.0, >= 2.0.8)
|
|
30
|
+
rack-test (>= 0.6.3)
|
|
31
|
+
rails-dom-testing (~> 2.0)
|
|
32
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
33
|
+
actiontext (6.0.3.2)
|
|
34
|
+
actionpack (= 6.0.3.2)
|
|
35
|
+
activerecord (= 6.0.3.2)
|
|
36
|
+
activestorage (= 6.0.3.2)
|
|
37
|
+
activesupport (= 6.0.3.2)
|
|
38
|
+
nokogiri (>= 1.8.5)
|
|
39
|
+
actionview (6.0.3.2)
|
|
40
|
+
activesupport (= 6.0.3.2)
|
|
41
|
+
builder (~> 3.1)
|
|
42
|
+
erubi (~> 1.4)
|
|
43
|
+
rails-dom-testing (~> 2.0)
|
|
44
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
45
|
+
activejob (6.0.3.2)
|
|
46
|
+
activesupport (= 6.0.3.2)
|
|
47
|
+
globalid (>= 0.3.6)
|
|
48
|
+
activemodel (6.0.3.2)
|
|
49
|
+
activesupport (= 6.0.3.2)
|
|
50
|
+
activerecord (6.0.3.2)
|
|
51
|
+
activemodel (= 6.0.3.2)
|
|
52
|
+
activesupport (= 6.0.3.2)
|
|
53
|
+
activestorage (6.0.3.2)
|
|
54
|
+
actionpack (= 6.0.3.2)
|
|
55
|
+
activejob (= 6.0.3.2)
|
|
56
|
+
activerecord (= 6.0.3.2)
|
|
57
|
+
marcel (~> 0.3.1)
|
|
58
|
+
activesupport (6.0.3.2)
|
|
59
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
60
|
+
i18n (>= 0.7, < 2)
|
|
61
|
+
minitest (~> 5.1)
|
|
62
|
+
tzinfo (~> 1.1)
|
|
63
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
|
64
|
+
ast (2.4.1)
|
|
65
|
+
builder (3.2.4)
|
|
66
|
+
combustion (1.3.0)
|
|
67
|
+
activesupport (>= 3.0.0)
|
|
68
|
+
railties (>= 3.0.0)
|
|
69
|
+
thor (>= 0.14.6)
|
|
70
|
+
concurrent-ruby (1.1.6)
|
|
71
|
+
crass (1.0.6)
|
|
72
|
+
diff-lcs (1.4.4)
|
|
73
|
+
erubi (1.9.0)
|
|
74
|
+
globalid (0.4.2)
|
|
75
|
+
activesupport (>= 4.2.0)
|
|
76
|
+
graphql (1.11.1)
|
|
77
|
+
i18n (1.8.5)
|
|
78
|
+
concurrent-ruby (~> 1.0)
|
|
79
|
+
loofah (2.6.0)
|
|
80
|
+
crass (~> 1.0.2)
|
|
81
|
+
nokogiri (>= 1.5.9)
|
|
82
|
+
mail (2.7.1)
|
|
83
|
+
mini_mime (>= 0.1.1)
|
|
84
|
+
marcel (0.3.3)
|
|
85
|
+
mimemagic (~> 0.3.2)
|
|
86
|
+
method_source (1.0.0)
|
|
87
|
+
mimemagic (0.3.5)
|
|
88
|
+
mini_mime (1.0.2)
|
|
89
|
+
mini_portile2 (2.4.0)
|
|
90
|
+
minitest (5.14.1)
|
|
91
|
+
nio4r (2.5.2)
|
|
92
|
+
nokogiri (1.10.10)
|
|
93
|
+
mini_portile2 (~> 2.4.0)
|
|
94
|
+
parallel (1.19.2)
|
|
95
|
+
parser (2.7.1.4)
|
|
96
|
+
ast (~> 2.4.1)
|
|
97
|
+
rack (2.2.3)
|
|
98
|
+
rack-test (1.1.0)
|
|
99
|
+
rack (>= 1.0, < 3)
|
|
100
|
+
rails (6.0.3.2)
|
|
101
|
+
actioncable (= 6.0.3.2)
|
|
102
|
+
actionmailbox (= 6.0.3.2)
|
|
103
|
+
actionmailer (= 6.0.3.2)
|
|
104
|
+
actionpack (= 6.0.3.2)
|
|
105
|
+
actiontext (= 6.0.3.2)
|
|
106
|
+
actionview (= 6.0.3.2)
|
|
107
|
+
activejob (= 6.0.3.2)
|
|
108
|
+
activemodel (= 6.0.3.2)
|
|
109
|
+
activerecord (= 6.0.3.2)
|
|
110
|
+
activestorage (= 6.0.3.2)
|
|
111
|
+
activesupport (= 6.0.3.2)
|
|
112
|
+
bundler (>= 1.3.0)
|
|
113
|
+
railties (= 6.0.3.2)
|
|
114
|
+
sprockets-rails (>= 2.0.0)
|
|
115
|
+
rails-dom-testing (2.0.3)
|
|
116
|
+
activesupport (>= 4.2.0)
|
|
117
|
+
nokogiri (>= 1.6)
|
|
118
|
+
rails-html-sanitizer (1.3.0)
|
|
119
|
+
loofah (~> 2.3)
|
|
120
|
+
railties (6.0.3.2)
|
|
121
|
+
actionpack (= 6.0.3.2)
|
|
122
|
+
activesupport (= 6.0.3.2)
|
|
123
|
+
method_source
|
|
124
|
+
rake (>= 0.8.7)
|
|
125
|
+
thor (>= 0.20.3, < 2.0)
|
|
126
|
+
rainbow (3.0.0)
|
|
127
|
+
rake (12.3.3)
|
|
128
|
+
regexp_parser (1.7.1)
|
|
129
|
+
rexml (3.2.4)
|
|
130
|
+
rspec (3.9.0)
|
|
131
|
+
rspec-core (~> 3.9.0)
|
|
132
|
+
rspec-expectations (~> 3.9.0)
|
|
133
|
+
rspec-mocks (~> 3.9.0)
|
|
134
|
+
rspec-core (3.9.2)
|
|
135
|
+
rspec-support (~> 3.9.3)
|
|
136
|
+
rspec-expectations (3.9.2)
|
|
137
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
138
|
+
rspec-support (~> 3.9.0)
|
|
139
|
+
rspec-mocks (3.9.1)
|
|
140
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
141
|
+
rspec-support (~> 3.9.0)
|
|
142
|
+
rspec-rails (4.0.1)
|
|
143
|
+
actionpack (>= 4.2)
|
|
144
|
+
activesupport (>= 4.2)
|
|
145
|
+
railties (>= 4.2)
|
|
146
|
+
rspec-core (~> 3.9)
|
|
147
|
+
rspec-expectations (~> 3.9)
|
|
148
|
+
rspec-mocks (~> 3.9)
|
|
149
|
+
rspec-support (~> 3.9)
|
|
150
|
+
rspec-support (3.9.3)
|
|
151
|
+
rubocop (0.88.0)
|
|
152
|
+
parallel (~> 1.10)
|
|
153
|
+
parser (>= 2.7.1.1)
|
|
154
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
155
|
+
regexp_parser (>= 1.7)
|
|
156
|
+
rexml
|
|
157
|
+
rubocop-ast (>= 0.1.0, < 1.0)
|
|
158
|
+
ruby-progressbar (~> 1.7)
|
|
159
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
|
160
|
+
rubocop-ast (0.2.0)
|
|
161
|
+
parser (>= 2.7.0.1)
|
|
162
|
+
rubocop-performance (1.7.1)
|
|
163
|
+
rubocop (>= 0.82.0)
|
|
164
|
+
rubocop-rspec (1.42.0)
|
|
165
|
+
rubocop (>= 0.87.0)
|
|
166
|
+
ruby-progressbar (1.10.1)
|
|
167
|
+
sprockets (4.0.2)
|
|
168
|
+
concurrent-ruby (~> 1.0)
|
|
169
|
+
rack (> 1, < 3)
|
|
170
|
+
sprockets-rails (3.2.1)
|
|
171
|
+
actionpack (>= 4.0)
|
|
172
|
+
activesupport (>= 4.0)
|
|
173
|
+
sprockets (>= 3.0.0)
|
|
174
|
+
sqlite3 (1.4.2)
|
|
175
|
+
thor (1.0.1)
|
|
176
|
+
thread_safe (0.3.6)
|
|
177
|
+
tzinfo (1.2.7)
|
|
178
|
+
thread_safe (~> 0.1)
|
|
179
|
+
unicode-display_width (1.7.0)
|
|
180
|
+
websocket-driver (0.7.3)
|
|
181
|
+
websocket-extensions (>= 0.1.0)
|
|
182
|
+
websocket-extensions (0.1.5)
|
|
183
|
+
zeitwerk (2.4.0)
|
|
184
|
+
|
|
185
|
+
PLATFORMS
|
|
186
|
+
ruby
|
|
187
|
+
|
|
188
|
+
DEPENDENCIES
|
|
189
|
+
combustion
|
|
190
|
+
graphql
|
|
191
|
+
graphql-eager_load!
|
|
192
|
+
rails
|
|
193
|
+
rake
|
|
194
|
+
rspec
|
|
195
|
+
rspec-rails
|
|
196
|
+
rubocop
|
|
197
|
+
rubocop-performance
|
|
198
|
+
rubocop-rspec
|
|
199
|
+
sqlite3
|
|
200
|
+
|
|
201
|
+
BUNDLED WITH
|
|
202
|
+
2.1.4
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Copyright (c) 2020 HOVER Inc.
|
data/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Graphql::EagerLoad
|
|
2
|
+
|
|
3
|
+
This gem traverses your graphql query looking for fields on types that match
|
|
4
|
+
associations on those types. For each field found to be an association, this
|
|
5
|
+
gem adds those associations to an [ActiveRecord::QueryMethods#includes](https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-includes) hash. That hash can then be used to
|
|
6
|
+
eager load the associations of records returned in your graphql resolver.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Add this line to your application's Gemfile:
|
|
11
|
+
|
|
12
|
+
```ruby
|
|
13
|
+
gem 'graphql-eager_load'
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
And then execute:
|
|
17
|
+
|
|
18
|
+
$ bundle install
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
module Resolvers
|
|
24
|
+
class Users < Resolvers::Base
|
|
25
|
+
eager_load_model ::User
|
|
26
|
+
|
|
27
|
+
type Types::User.connection_type, null: false
|
|
28
|
+
|
|
29
|
+
def resolve
|
|
30
|
+
User.active.includes(associations_to_eager_load)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The `.eager_load_model` and `#associations_to_eager_load` methods are provided by this gem.
|
|
37
|
+
|
|
38
|
+
## Development
|
|
39
|
+
|
|
40
|
+
After checking out the repo, run `bundle` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bundle exec bin/console` for an interactive prompt that will allow you to experiment.
|
|
41
|
+
|
|
42
|
+
To release a new version:
|
|
43
|
+
|
|
44
|
+
- Update the version number in `version.rb`
|
|
45
|
+
- Make a PR with your changes and the version number increment
|
|
46
|
+
- After the PR is merged, make the new release https://github.com/hoverinc/graphql-eager-load/releases
|
|
47
|
+
|
|
48
|
+
## Contributing
|
|
49
|
+
|
|
50
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/hoverinc/graphql-eager-load.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
MIT
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'graphql/eager_load'
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require 'irb'
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/config.ru
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/graphql/eager_load/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'graphql-eager_load'
|
|
7
|
+
spec.version = Graphql::EagerLoad::VERSION
|
|
8
|
+
spec.authors = ['Elise Wood']
|
|
9
|
+
spec.email = ['elise@hover.to']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'Generate ActiveRecord eager loading options from GraphQL Queries.'
|
|
12
|
+
spec.description = ''
|
|
13
|
+
spec.homepage = 'https://github.com/hoverinc/graphql-eager-load'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
|
16
|
+
|
|
17
|
+
# spec.metadata['allowed_push_host'] = 'github.com/hoverinc/graphql-eager-load'
|
|
18
|
+
|
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
20
|
+
spec.metadata['source_code_uri'] = 'https://github.com/hoverinc/graphql-eager-load'
|
|
21
|
+
spec.metadata['changelog_uri'] = 'https://github.com/hoverinc/graphql-eager-load/commits'
|
|
22
|
+
|
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
27
|
+
end
|
|
28
|
+
spec.bindir = 'exe'
|
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
30
|
+
spec.require_paths = ['lib']
|
|
31
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Graphql
|
|
4
|
+
module EagerLoad
|
|
5
|
+
#
|
|
6
|
+
# Given
|
|
7
|
+
# - An initial set of includes, a hash
|
|
8
|
+
# - GraphQL query selections
|
|
9
|
+
# - The model corresponding to the type returned by a GraphQL resolver
|
|
10
|
+
#
|
|
11
|
+
# This module will iterate and recurse into the selctions to find out if
|
|
12
|
+
# any of the fields requested for a given type corresponds to an
|
|
13
|
+
# association on the ActiveRecord model associated with the field's type.
|
|
14
|
+
#
|
|
15
|
+
#
|
|
16
|
+
# For example given this query
|
|
17
|
+
#
|
|
18
|
+
# salesOpportunities() {
|
|
19
|
+
# soldEstimateGroup {
|
|
20
|
+
# estimates {
|
|
21
|
+
# lineItems
|
|
22
|
+
# }
|
|
23
|
+
# }
|
|
24
|
+
# }
|
|
25
|
+
#
|
|
26
|
+
# We'd return this "includes" hash
|
|
27
|
+
#
|
|
28
|
+
# {sold_estimate_group: {estimates: {line_items: {}}}}
|
|
29
|
+
#
|
|
30
|
+
# And our resolver will use it like `scope.includes(includes)` to
|
|
31
|
+
# prevent N+1s
|
|
32
|
+
#
|
|
33
|
+
class Builder
|
|
34
|
+
def self.call(selections:, model:)
|
|
35
|
+
selections.each.with_object({}) do |selection, includes|
|
|
36
|
+
builder = new(selection: selection, model: model)
|
|
37
|
+
|
|
38
|
+
if builder.association?
|
|
39
|
+
hash = builder.includes
|
|
40
|
+
hash[:blob] ||= {} if builder.active_storage_attachment?
|
|
41
|
+
includes[builder.association_name] = hash
|
|
42
|
+
else
|
|
43
|
+
includes.merge!(builder.includes)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def initialize(selection:, model:)
|
|
49
|
+
@selection = selection
|
|
50
|
+
@model = model
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def includes
|
|
54
|
+
self.class.call(selections: selection.selections, model: includes_model)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def association?
|
|
58
|
+
association.present?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def association_name
|
|
62
|
+
association.name
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def active_storage_attachment?
|
|
66
|
+
model.reflect_on_attachment(field_name).present?
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
attr_reader :selection, :model
|
|
72
|
+
|
|
73
|
+
def includes_model
|
|
74
|
+
return ActiveStorage::Attachment if active_storage_attachment?
|
|
75
|
+
|
|
76
|
+
association&.klass || model
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def association
|
|
80
|
+
return if use_custom_method?
|
|
81
|
+
return model.reflect_on_association("#{field_name}_attachment") if active_storage_attachment?
|
|
82
|
+
|
|
83
|
+
model.reflect_on_association(field_name)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def use_custom_method?
|
|
87
|
+
custom_method_defined? && !ignore_custom_method?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def ignore_custom_method?
|
|
91
|
+
return false unless field_owner.respond_to?(:allow_include_builder_fields)
|
|
92
|
+
|
|
93
|
+
field_owner.allow_include_builder_fields&.include?(field_name.to_sym)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def custom_method_defined?
|
|
97
|
+
field_owner.instance_methods.include?(field_name)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def field_owner
|
|
101
|
+
selection.field.owner
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def field_name
|
|
105
|
+
selection.name
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Graphql
|
|
4
|
+
module EagerLoad
|
|
5
|
+
# Automatically included in any subclasses of Resolvers::Base
|
|
6
|
+
module Resolver
|
|
7
|
+
def self.included(klass)
|
|
8
|
+
klass.extend(ClassMethods)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def associations_to_include
|
|
12
|
+
graphql_eager_load_options(model: self.class.class_variable_get(:@@eager_load_model))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def graphql_eager_load_options(selections: context.query.lookahead.selections, model:)
|
|
16
|
+
Builder.call(selections: selections, model: model)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# specify the ActiveRecord model that corresponds to the top level type
|
|
20
|
+
# in the graphql query for this resolver.
|
|
21
|
+
module ClassMethods
|
|
22
|
+
def eager_load_model(model)
|
|
23
|
+
# rubocop:disable Style/ClassVars
|
|
24
|
+
class_variable_set(:@@eager_load_model, model)
|
|
25
|
+
# rubocop:enable Style/ClassVars
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: graphql-eager_load
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Elise Wood
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2020-08-11 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: ''
|
|
14
|
+
email:
|
|
15
|
+
- elise@hover.to
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- ".github/workflows/test.yml"
|
|
21
|
+
- ".gitignore"
|
|
22
|
+
- ".rspec"
|
|
23
|
+
- ".rubocop.yml"
|
|
24
|
+
- ".travis.yml"
|
|
25
|
+
- Gemfile
|
|
26
|
+
- Gemfile.lock
|
|
27
|
+
- LICENSE.txt
|
|
28
|
+
- README.md
|
|
29
|
+
- Rakefile
|
|
30
|
+
- bin/console
|
|
31
|
+
- bin/setup
|
|
32
|
+
- config.ru
|
|
33
|
+
- graphql-eager-load.gemspec
|
|
34
|
+
- lib/graphql/eager_load.rb
|
|
35
|
+
- lib/graphql/eager_load/builder.rb
|
|
36
|
+
- lib/graphql/eager_load/resolver.rb
|
|
37
|
+
- lib/graphql/eager_load/version.rb
|
|
38
|
+
homepage: https://github.com/hoverinc/graphql-eager-load
|
|
39
|
+
licenses:
|
|
40
|
+
- MIT
|
|
41
|
+
metadata:
|
|
42
|
+
homepage_uri: https://github.com/hoverinc/graphql-eager-load
|
|
43
|
+
source_code_uri: https://github.com/hoverinc/graphql-eager-load
|
|
44
|
+
changelog_uri: https://github.com/hoverinc/graphql-eager-load/commits
|
|
45
|
+
post_install_message:
|
|
46
|
+
rdoc_options: []
|
|
47
|
+
require_paths:
|
|
48
|
+
- lib
|
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 2.3.0
|
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '0'
|
|
59
|
+
requirements: []
|
|
60
|
+
rubygems_version: 3.1.2
|
|
61
|
+
signing_key:
|
|
62
|
+
specification_version: 4
|
|
63
|
+
summary: Generate ActiveRecord eager loading options from GraphQL Queries.
|
|
64
|
+
test_files: []
|