Class: Graphql::HydrateQuery

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/hydrate_query.rb

Instance Method Summary collapse

Constructor Details

#initialize(model, context, check_visibility: true, id: nil, user: nil) ⇒ HydrateQuery

Returns a new instance of HydrateQuery.



4
5
6
7
8
9
10
11
# File 'lib/graphql/hydrate_query.rb', line 4

def initialize(model, context, check_visibility: true, id: nil, user: nil)
  @fields = context&.irep_node&.scoped_children&.values&.first
  @model = model
  @models = [model_name.singularize.camelize]
  @check_visibility = check_visibility
  @id = id
  @user = user
end

Instance Method Details

#activerecord_model?(name) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
# File 'lib/graphql/hydrate_query.rb', line 50

def activerecord_model?(name)
  class_name = name.to_s.singularize.camelize
  begin
    class_name.constantize.ancestors.include?(ApplicationRecord)
  rescue NameError
    false
  end
end

#evaluate_model(parent, child) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/graphql/hydrate_query.rb', line 59

def evaluate_model(parent, child)
  child_class_name = child.to_s.singularize.camelize
  parent_class_name = parent.to_s.singularize.camelize
  return child_class_name.constantize if activerecord_model?(child_class_name)
  return unless activerecord_model?(parent_class_name)
  parent_class_name.constantize.reflections[child.to_s.underscore]&.klass
end

#hash_to_array_of_hashes(hash, parent_class) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/graphql/hydrate_query.rb', line 39

def hash_to_array_of_hashes(hash, parent_class)
  return if parent_class.nil?
  hash['id'] = nil if hash['id'].blank?
  hash.each_with_object([]) do |(k, v), arr|
    next arr << k if v.blank? && parent_class.new.attributes.key?(k)
    klass = evaluate_model(parent_class, k)
    @models << klass.to_s unless @models.include?(klass.to_s)
    arr << { k.to_sym => hash_to_array_of_hashes(v, klass) } if klass.present? && v.present?
  end
end

#hash_to_struct(hash, parent_model) ⇒ Object



24
25
26
27
28
29
30
31
# File 'lib/graphql/hydrate_query.rb', line 24

def hash_to_struct(hash, parent_model)
  return if !visibility_hash[parent_model].include?(hash['id']) && @check_visibility
  hash.each_with_object(OpenStruct.new) do |(k, v), struct|
    next struct[k.to_sym] = plucked_attr_to_structs(v, evaluate_model(parent_model, k)) if v.is_a?(Array)
    next struct[k.to_sym] = hash_to_struct(v, evaluate_model(parent_model, k)) if v.is_a?(Hash)
    struct[k.to_sym] = v
  end
end

#model_nameObject



73
74
75
# File 'lib/graphql/hydrate_query.rb', line 73

def model_name
  @model.class.to_s.split('::').first.underscore.pluralize
end

#parse_fields(fields) ⇒ Object



67
68
69
70
71
# File 'lib/graphql/hydrate_query.rb', line 67

def parse_fields(fields)
  fields.each_with_object({}) do |(k, v), h|
    h[k] = v.scoped_children == {} ? nil : parse_fields(v.scoped_children.values.first)
  end
end

#plucked_attr_to_structs(arr, parent_model) ⇒ Object



20
21
22
# File 'lib/graphql/hydrate_query.rb', line 20

def plucked_attr_to_structs(arr, parent_model)
  arr.map { |e| hash_to_struct(e, parent_model) }
end

#runObject



13
14
15
16
17
18
# File 'lib/graphql/hydrate_query.rb', line 13

def run
  @model = @model.where(id: @id) if @id
  plucked = @model.deep_pluck(*hash_to_array_of_hashes(parse_fields(@fields), @model))
  result = plucked_attr_to_structs(plucked, model_name.singularize.camelize.constantize)
  @id ? result.first : result
end

#visibility_hashObject



33
34
35
36
37
# File 'lib/graphql/hydrate_query.rb', line 33

def visibility_hash
  @visibility_hash ||= @models.each_with_object({}) do |model, hash|
    hash[model.constantize] = model.constantize.visible_for(user: @user).pluck(:id)
  end
end