Class: Fields::Serializer::FieldsTree

Inherits:
Object
  • Object
show all
Defined in:
lib/fields/serializer/fields_tree.rb

Overview

A class to store a tree structure of a model klass, its attributes and associations.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ FieldsTree

Returns a new instance of FieldsTree.



11
12
13
14
15
# File 'lib/fields/serializer/fields_tree.rb', line 11

def initialize(klass)
  @klass        = klass
  @fields       = []
  @associations = {}
end

Instance Attribute Details

#associationsObject (readonly)

Returns the value of attribute associations.



9
10
11
# File 'lib/fields/serializer/fields_tree.rb', line 9

def associations
  @associations
end

#fieldsObject (readonly)

Returns the value of attribute fields.



9
10
11
# File 'lib/fields/serializer/fields_tree.rb', line 9

def fields
  @fields
end

#klassObject (readonly)

Returns the value of attribute klass.



9
10
11
# File 'lib/fields/serializer/fields_tree.rb', line 9

def klass
  @klass
end

Instance Method Details

#merge!(join_field) ⇒ Object

Adds a new field (json api notation) to the tree structure:

user_tree.notation
  #=> [:name, :surname, { subjects: [:title, { posts: { comments: :count } }], followers: :nickname }]

user_tree.merge!("subjects.posts.date").notation
  #=> [:name, :surname, { subjects: [:title, { posts: [{ comments: :count }, :date] }], followers: :nickname }]


29
30
31
32
33
34
35
36
37
38
# File 'lib/fields/serializer/fields_tree.rb', line 29

def merge!(join_field)
  return self unless join_field.present?
  parent, rest = join_field.to_s.split(".", 2)
  if rest.blank?
    fields << parent if !(existing_field?(parent) || association?(parent))
  else
    existing_association?(parent) ? associations[parent].merge!(rest) : add_association!(parent, rest)
  end
  self
end

#notationObject

Return the tree structure in Rails includes notation including both associations and fields

user_tree.notation
  #=> [:name, :surname, { subjects: [:title, { posts: :comments }], followers: :nickname }]


45
46
47
48
49
50
51
52
53
54
55
# File 'lib/fields/serializer/fields_tree.rb', line 45

def notation
  if fields.present?
    if associations.present?
      fields.dup << associations_to_notation
    else
      fields.one? ? fields.first.dup : fields.dup
    end
  else
    associations_to_notation.presence
  end
end

#presenceObject



17
18
19
# File 'lib/fields/serializer/fields_tree.rb', line 17

def presence
  self if fields.present? || associations.present?
end

#to_includesObject

Return the tree structure in Rails includes notation including only associations

user_tree.notation
  #=> [{ subjects: { posts: :comments }}, :followers]


62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/fields/serializer/fields_tree.rb', line 62

def to_includes
  to_includes = associations.inject([]) do |result, (k, v)|
    v_includes = v.to_includes
    if v_includes.present?
      new_has_entry = { k => v_includes }
      hash = result.find { |e| e.is_a?(Hash) }
      hash ? hash.merge!(new_has_entry) : (result << new_has_entry)
      result
    else
      result << k
    end
  end.presence
  Array.wrap(to_includes).one? ? to_includes.first : to_includes
end

#to_sObject



77
78
79
# File 'lib/fields/serializer/fields_tree.rb', line 77

def to_s
  notation.to_s
end