graphql_includable 0.2.3 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67916fbd68ce3698cbecbc818655408ba89f8f1a
4
- data.tar.gz: 930edfc340b740528fd689b2bfd196f2f81aeef8
3
+ metadata.gz: 6545a0cd3202a2d518e38696954b7797fd185684
4
+ data.tar.gz: 484b44d89aacbc52585f73657646fd12cd770ef6
5
5
  SHA512:
6
- metadata.gz: 48fe0a1f6e0bb028e7f643df33ecfcecec7701cfc382f33cb0928305a00fa6b6007e3e71ed5890be67b25d50c41079dfbfdbaece299c18e1c47f85ed116ad8a0
7
- data.tar.gz: cd524919a412f7e98dff775b2b676d16c6fd30868c8f63f982c44e6a10110cd3cbb7dc2ecf93d0d91034561f3282b47a804e67afd3845cbc538e3c66891839f9
6
+ metadata.gz: 8c3562e409a36d572f2899d21317a382eacda8d0c8f5413f0faa37423a5161c83278b7182dd99146c1bc3be095bfddd5419fa3ae279056b50964f5a66407b900
7
+ data.tar.gz: afe70bfba8d8f6459ff67301e44de68a5bcb66309ef9c293e803b8e77a6a05f05c5a812a2f55d99a56d2968d538f50a3d727c2011f1b6a47ca3b8e0aeba76922
@@ -0,0 +1,105 @@
1
+ module GraphQLIncludable
2
+ class Resolver
3
+ # Returns the first node in the tree which returns a specific type
4
+ def self.find_node_by_return_type(node, desired_return_type)
5
+ return_type = node.return_type.unwrap
6
+ return node if return_type == desired_return_type
7
+ if node.respond_to?(:scoped_children)
8
+ node.scoped_children[return_type].find do |_child_name, child_node|
9
+ find_node_by_return_type(child_node, desired_return_type)
10
+ end
11
+ end
12
+ end
13
+
14
+ # Translate a node's selections into `includes` values
15
+ # Combine and format children values
16
+ # Noop on nodes that don't return AR (so no associations to include)
17
+ def self.includes_for_node(node)
18
+ return_model = node_return_model(node)
19
+ return [] if return_model.blank?
20
+
21
+ children = node.scoped_children[node.return_type.unwrap]
22
+ nested_includes = {}
23
+
24
+ children.each_value do |child_node|
25
+ child_includes = includes_for_child(child_node, return_model)
26
+
27
+ if child_includes.is_a?(Hash)
28
+ nested_includes.merge!(child_includes)
29
+ elsif child_includes.is_a?(Array)
30
+ includes += child_includes
31
+ else
32
+ includes << child_includes
33
+ end
34
+ end
35
+
36
+ includes << nested_includes if nested_includes.present?
37
+ includes.uniq
38
+ end
39
+
40
+ def self.includes_for_child(node, parent_model)
41
+ attribute_name = node_predicted_association_name(node)
42
+ delegated_through = includes_delegated_through(parent_model, attribute_name)
43
+ delegated_model = model_name_to_class(delegated_through.last) if delegated_through.present?
44
+ (delegated_model || parent_model).reflect_on_association(association_name)
45
+ association = get_model_association(parent_model, attribute_name, interceding_includes)
46
+
47
+ if association
48
+ child_includes = includes_for_node(node)
49
+ array_to_nested_hash(interceding_includes + [attribute_name, child_includes].reject(&:blank?))
50
+ # if node_is_relay_connection?(node)
51
+ # join_name = association.options[:through]
52
+ # edge_includes_chain = [association.name]
53
+ # edge_includes_chain << child_includes.pop[association.name.to_s.singularize.to_sym] if child_includes.last&.is_a?(Hash)
54
+ # edge_includes = array_to_nested_hash(edge_includes_chain)
55
+ # end
56
+ else
57
+ [array_to_nested_hash(interceding_includes), specified_includes].reject(&:blank?)
58
+ end
59
+ end
60
+
61
+ def self.model_name_to_class(model_name)
62
+ begin
63
+ model_name.to_s.camelize.constantize
64
+ rescue NameError
65
+ model_name.to_s.singularize.camelize.constantize
66
+ end
67
+ rescue
68
+ end
69
+
70
+ # Translate a node's return type to an ActiveRecord model
71
+ def self.node_return_model(node)
72
+ model = Object.const_get(node.return_type.unwrap.name.gsub(/(^SquareFoot|Edge$|Connection$)/, ''))
73
+ model if model < ActiveRecord::Base
74
+ rescue NameError
75
+ end
76
+
77
+ def self.node_predicted_association_name(node)
78
+ definition = node.definitions.first
79
+ definition.metadata[:includes] || (definition.property || definition.name).to_sym
80
+ end
81
+
82
+ # If method_name is delegated from base_model, return an array of
83
+ # associations through which those methods can be delegated
84
+ def self.includes_delegated_through(base_model, method_name)
85
+ chain = []
86
+ method = method_name.to_sym
87
+ model_name = base_model.instance_variable_get(:@delegate_cache).try(:[], method)
88
+ while model_name
89
+ chain << model_name
90
+ model = model_name_to_class(model_name)
91
+ model_name = model.instance_variable_get(:@delegate_cache).try(:[], method)
92
+ end
93
+ chain
94
+ end
95
+
96
+ # Right-reduce an array into a nested hash
97
+ def self.array_to_nested_hash(arr)
98
+ arr.reverse.inject { |acc, item| { item => acc } } || {}
99
+ end
100
+
101
+ # def self.node_is_relay_connection?(node)
102
+ # node.return_type.unwrap.name =~ /Connection$/
103
+ # end
104
+ end
105
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql_includable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Rouse
@@ -22,6 +22,7 @@ files:
22
22
  - lib/graphql_includable.rb
23
23
  - lib/graphql_includable/concern.rb
24
24
  - lib/graphql_includable/edge.rb
25
+ - lib/graphql_includable/resolver.rb
25
26
  homepage: https://github.com/thesquarefoot/graphql_includable
26
27
  licenses:
27
28
  - MIT