graphiti_gql 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/graphiti_gql/graphiti_hax.rb +34 -1
- data/lib/graphiti_gql/loaders/many_to_many.rb +20 -3
- data/lib/graphiti_gql/schema/fields/attribute.rb +31 -7
- data/lib/graphiti_gql/schema/fields/to_many.rb +32 -1
- data/lib/graphiti_gql/version.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff76a3032a8378019cc0034c48cc1bd33302a8d662515fd722d970e642ee355e
|
4
|
+
data.tar.gz: 532980890cd827d260bceebd5f944eeb999a561cde6df3e14cff5ddbfaa5f146
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a67a1e359377aa6682b2f23fd0461b2547a05df41c14739d4abf691d879682dd8cd83a4e4deda386855ae6c7a587feb453b2aff5490d2e0d44998955ff6bba9
|
7
|
+
data.tar.gz: f5f83d5859fc24f3215723d3abd7d1105dcefc3f02002853f829a4d954923444df0d1a37c0cbbb736dbb79df9745dd1be1c197c6151b07febb117272eb12e8e7
|
data/Gemfile.lock
CHANGED
@@ -121,6 +121,24 @@ module GraphitiGql
|
|
121
121
|
end
|
122
122
|
Graphiti::Scoping::Paginate.send(:prepend, PaginateExtras)
|
123
123
|
|
124
|
+
module ManyToManyExtras
|
125
|
+
extend ActiveSupport::Concern
|
126
|
+
|
127
|
+
class_methods do
|
128
|
+
attr_accessor :edge_resource
|
129
|
+
|
130
|
+
def attribute(*args, &blk)
|
131
|
+
@edge_resource = Class.new(Graphiti::Resource) do
|
132
|
+
def self.abstract_class?
|
133
|
+
true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
@edge_resource.attribute(*args, &blk)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
Graphiti::Sideload::ManyToMany.send(:include, ManyToManyExtras)
|
141
|
+
|
124
142
|
module StatsExtras
|
125
143
|
def calculate_stat(name, function)
|
126
144
|
config = @resource.all_attributes[name] || {}
|
@@ -166,7 +184,9 @@ module GraphitiGql
|
|
166
184
|
alias_method :filter_precise_datetime_not_eq, :filter_not_eq
|
167
185
|
end
|
168
186
|
end
|
169
|
-
Graphiti::Adapters::ActiveRecord
|
187
|
+
if defined?(Graphiti::Adapters::ActiveRecord)
|
188
|
+
Graphiti::Adapters::ActiveRecord.send(:include, ActiveRecordAdapterExtras)
|
189
|
+
end
|
170
190
|
|
171
191
|
Graphiti::Adapters::Abstract.class_eval do
|
172
192
|
class << self
|
@@ -215,4 +235,17 @@ module GraphitiGql
|
|
215
235
|
end
|
216
236
|
end
|
217
237
|
Graphiti::Scope.send(:prepend, ScopeExtras)
|
238
|
+
|
239
|
+
module ActiveRecordManyToManyExtras
|
240
|
+
# flipping .includes to .joins
|
241
|
+
def belongs_to_many_filter(scope, value)
|
242
|
+
scope
|
243
|
+
.joins(through_relationship_name)
|
244
|
+
.where(belongs_to_many_clause(value, type))
|
245
|
+
end
|
246
|
+
end
|
247
|
+
if defined?(ActiveRecord)
|
248
|
+
::Graphiti::Adapters::ActiveRecord::ManyToManySideload
|
249
|
+
.send(:prepend, ActiveRecordManyToManyExtras)
|
250
|
+
end
|
218
251
|
end
|
@@ -2,15 +2,32 @@ module GraphitiGql
|
|
2
2
|
module Loaders
|
3
3
|
class ManyToMany < Many
|
4
4
|
def assign(ids, proxy)
|
5
|
-
records = proxy.data
|
6
5
|
thru = @sideload.foreign_key.keys.first
|
7
6
|
fk = @sideload.foreign_key[thru]
|
7
|
+
add_join_table_magic(proxy)
|
8
|
+
records = proxy.data
|
8
9
|
ids.each do |id|
|
9
|
-
|
10
|
-
|
10
|
+
corresponding = records.select do |record|
|
11
|
+
record.send(:"_edge_#{fk}") == id
|
12
|
+
end
|
11
13
|
fulfill(id, [corresponding, proxy])
|
12
14
|
end
|
13
15
|
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def add_join_table_magic(proxy)
|
20
|
+
if defined?(ActiveRecord) && proxy.resource.model.ancestors.include?(ActiveRecord::Base)
|
21
|
+
thru = @sideload.foreign_key.keys.first
|
22
|
+
thru_model = proxy.resource.model.reflect_on_association(thru).klass
|
23
|
+
names = thru_model.column_names.map do |n|
|
24
|
+
"#{thru_model.table_name}.#{n} as _edge_#{n}"
|
25
|
+
end
|
26
|
+
scope = proxy.scope.object
|
27
|
+
scope = scope.select(["#{proxy.resource.model.table_name}.*"] + names)
|
28
|
+
proxy.scope.object = scope
|
29
|
+
end
|
30
|
+
end
|
14
31
|
end
|
15
32
|
end
|
16
33
|
end
|
@@ -2,10 +2,12 @@ module GraphitiGql
|
|
2
2
|
class Schema
|
3
3
|
module Fields
|
4
4
|
class Attribute
|
5
|
-
|
5
|
+
# If sideload is present, we're applying m2m metadata to an edge
|
6
|
+
def initialize(name, config, sideload = nil)
|
6
7
|
@config = config
|
7
8
|
@name = name
|
8
9
|
@alias = config[:alias]
|
10
|
+
@sideload = sideload # is_edge: true
|
9
11
|
end
|
10
12
|
|
11
13
|
def apply(type)
|
@@ -13,20 +15,39 @@ module GraphitiGql
|
|
13
15
|
_config = @config
|
14
16
|
_name = @name
|
15
17
|
_alias = @alias
|
18
|
+
_sideload = @sideload
|
16
19
|
opts = @config.slice(:null, :deprecation_reason)
|
17
20
|
type.field(_name, field_type, **opts)
|
18
21
|
type.define_method _name do
|
19
22
|
if (readable = _config[:readable]).is_a?(Symbol)
|
20
|
-
|
23
|
+
obj = object
|
24
|
+
obj = object.node if _sideload
|
25
|
+
resource = obj.instance_variable_get(:@__graphiti_resource)
|
21
26
|
unless resource.send(readable)
|
22
27
|
path = Graphiti.context[:object][:current_path].join(".")
|
23
28
|
raise Errors::UnauthorizedField.new(path)
|
24
29
|
end
|
25
30
|
end
|
31
|
+
|
32
|
+
edge_attrs = nil
|
33
|
+
if _sideload
|
34
|
+
edge_attrs = object.node.attributes
|
35
|
+
.select { |k, v| k.to_s.starts_with?("_edge_") }
|
36
|
+
edge_attrs.transform_keys! { |k| k.to_s.gsub("_edge_", "").to_sym }
|
37
|
+
end
|
38
|
+
|
26
39
|
value = if _config[:proc]
|
27
|
-
|
40
|
+
if _sideload
|
41
|
+
instance_exec(edge_attrs, &_config[:proc])
|
42
|
+
else
|
43
|
+
instance_eval(&_config[:proc])
|
44
|
+
end
|
28
45
|
else
|
29
|
-
|
46
|
+
if _sideload
|
47
|
+
edge_attrs[_alias || _name]
|
48
|
+
else
|
49
|
+
object.send(_alias || _name)
|
50
|
+
end
|
30
51
|
end
|
31
52
|
return if value.nil?
|
32
53
|
Graphiti::Types[_config[:type]][:read].call(value)
|
@@ -36,9 +57,12 @@ module GraphitiGql
|
|
36
57
|
private
|
37
58
|
|
38
59
|
def field_type
|
39
|
-
|
40
|
-
field_type
|
41
|
-
|
60
|
+
field_type = Graphiti::Types[@config[:type]][:graphql_type]
|
61
|
+
if !field_type
|
62
|
+
canonical_graphiti_type = Graphiti::Types.name_for(@config[:type])
|
63
|
+
field_type = GQL_TYPE_MAP[canonical_graphiti_type.to_sym]
|
64
|
+
field_type = String if @name == :id
|
65
|
+
end
|
42
66
|
field_type = [field_type] if @config[:type].to_s.starts_with?("array_of")
|
43
67
|
field_type
|
44
68
|
end
|
@@ -4,7 +4,11 @@ module GraphitiGql
|
|
4
4
|
class ToMany
|
5
5
|
def initialize(sideload, sideload_type)
|
6
6
|
@sideload = sideload
|
7
|
-
@sideload_type =
|
7
|
+
@sideload_type = if customized_edge?
|
8
|
+
build_customized_edge_type(sideload_type)
|
9
|
+
else
|
10
|
+
sideload_type
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
def apply(type)
|
@@ -31,6 +35,33 @@ module GraphitiGql
|
|
31
35
|
Loaders::Many.factory(_sideload, params).load(id)
|
32
36
|
end
|
33
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def customized_edge?
|
42
|
+
@sideload.type == :many_to_many && @sideload.class.edge_resource
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_customized_edge_type(sideload_type)
|
46
|
+
# build the edge class
|
47
|
+
prior_edge_class = sideload_type.edge_type_class
|
48
|
+
edge_class = Class.new(prior_edge_class)
|
49
|
+
edge_resource = @sideload.class.edge_resource
|
50
|
+
edge_resource.attributes.each_pair do |name, config|
|
51
|
+
next if name == :id
|
52
|
+
Schema::Fields::Attribute.new(name, config, @sideload).apply(edge_class)
|
53
|
+
end
|
54
|
+
registered_parent = Schema.registry.get(@sideload.parent_resource.class)
|
55
|
+
parent_name = registered_parent[:type].graphql_name
|
56
|
+
edge_class.define_method :graphql_name do
|
57
|
+
"#{parent_name}To#{sideload_type.graphql_name}Edge"
|
58
|
+
end
|
59
|
+
|
60
|
+
# build the sideload type with new edge class applied
|
61
|
+
klass = Class.new(sideload_type)
|
62
|
+
klass.edge_type_class(edge_class)
|
63
|
+
klass
|
64
|
+
end
|
34
65
|
end
|
35
66
|
end
|
36
67
|
end
|
data/lib/graphiti_gql/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphiti_gql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lee Richmond
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06-
|
11
|
+
date: 2022-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -108,7 +108,7 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '7.0'
|
111
|
-
description:
|
111
|
+
description:
|
112
112
|
email:
|
113
113
|
- richmolj@gmail.com
|
114
114
|
executables: []
|
@@ -167,7 +167,7 @@ licenses:
|
|
167
167
|
- MIT
|
168
168
|
metadata:
|
169
169
|
homepage_uri: https://www.graphiti.dev
|
170
|
-
post_install_message:
|
170
|
+
post_install_message:
|
171
171
|
rdoc_options: []
|
172
172
|
require_paths:
|
173
173
|
- lib
|
@@ -182,8 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
182
|
- !ruby/object:Gem::Version
|
183
183
|
version: '0'
|
184
184
|
requirements: []
|
185
|
-
rubygems_version: 3.
|
186
|
-
signing_key:
|
185
|
+
rubygems_version: 3.3.7
|
186
|
+
signing_key:
|
187
187
|
specification_version: 4
|
188
188
|
summary: GraphQL support for Graphiti
|
189
189
|
test_files: []
|