Module: GraphQLIncludable

Extended by:
ActiveSupport::Concern
Defined in:
lib/graphql_includable.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Class Method Details

.find_child_node_matching_model_name(node, model_name) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/graphql_includable.rb', line 35

def self.find_child_node_matching_model_name(node, model_name)
  matching_node = nil
  return_type = unwrapped_type(node)
  if return_type.to_s == model_name
    matching_node = node
  elsif node.respond_to? :scoped_children
    node.scoped_children[return_type].each do |child_name, child_node|
      matching_node = find_child_node_matching_model_name(child_node, model_name)
      break if matching_node
    end
  end
  matching_node
end

.generate_includes_from_graphql(query_context, model_name) ⇒ Object



30
31
32
33
# File 'lib/graphql_includable.rb', line 30

def self.generate_includes_from_graphql(query_context, model_name)
  matching_node = GraphQLIncludable.find_child_node_matching_model_name(query_context.irep_node, model_name)
  GraphQLIncludable.includes_from_irep_node(matching_node)
end

.get_delegated_model(model, method_name) ⇒ Object



116
117
118
# File 'lib/graphql_includable.rb', line 116

def self.get_delegated_model(model, method_name)
  model.instance_variable_get('@delegate_cache').try(:[], method_name.to_sym)
end

.includes_from_irep_node(node) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/graphql_includable.rb', line 49

def self.includes_from_irep_node(node)
  includes = []
  nested_includes = {}

  return_type = unwrapped_type(node)
  return_model = node_return_class(node)
  return [] unless node && return_type && return_model

  node.scoped_children[return_type].each do |child_name, child_node|
    specified_includes = child_node.definitions[0].[:includes]
    raw_association_name = (child_node.definitions[0].property || child_name).to_sym
    raw_association_name = specified_includes if specified_includes.is_a?(Symbol)
    delegated_model_name = get_delegated_model(return_model, raw_association_name)
    association_name = delegated_model_name || raw_association_name
    association = return_model.reflect_on_association(association_name)

    if association
      child_includes = includes_from_irep_node(child_node)
      if node_has_active_record_children(child_node) && child_includes.size > 0
        child_key = delegated_model_name || association_name
        nested_includes[child_key] = wrap_delegate(child_includes, delegated_model_name, raw_association_name)
      else
        includes << wrap_delegate(specified_includes || association_name, delegated_model_name)
      end
    elsif specified_includes
      includes << specified_includes
    end
  end

  includes << nested_includes if nested_includes.size > 0
  includes
end

.node_has_active_record_children(node) ⇒ Object



82
83
84
85
86
# File 'lib/graphql_includable.rb', line 82

def self.node_has_active_record_children(node)
  node.scoped_children[unwrapped_type(node)].each do |child_return_name, child_node|
    node_returns_active_record?(child_node)
  end
end

.node_return_class(node) ⇒ Object



88
89
90
91
92
93
# File 'lib/graphql_includable.rb', line 88

def self.node_return_class(node)
  begin
    Object.const_get(unwrapped_type(node).name)
  rescue NameError
  end
end

.node_returns_active_record?(node) ⇒ Boolean



95
96
97
98
# File 'lib/graphql_includable.rb', line 95

def self.node_returns_active_record?(node)
  klass = node_return_class(node)
  klass && klass < ActiveRecord::Base
end

.unwrapped_type(node) ⇒ Object

unwrap GraphQL ListType and NonNullType wrappers



110
111
112
113
114
# File 'lib/graphql_includable.rb', line 110

def self.unwrapped_type(node)
  type = node.return_type
  type = type.of_type while type.respond_to? :of_type
  type
end

.wrap_delegate(contents, delegate, delegate_key = delegate) ⇒ Object

return raw contents, or contents wrapped in a hash (for delegated associations)



101
102
103
104
105
106
107
# File 'lib/graphql_includable.rb', line 101

def self.wrap_delegate(contents, delegate, delegate_key = delegate)
  return contents unless delegate

  obj = {}
  obj[delegate_key] = contents
  obj
end