Module: ForestAdminDatasourceMongoid::Utils::Helpers

Included in:
Collection, Datasource, Schema::FieldsGenerator, Schema::MongoidSchema, Schema::RelationGenerator
Defined in:
lib/forest_admin_datasource_mongoid/utils/helpers.rb

Instance Method Summary collapse

Instance Method Details

#compare_ids(id_a, id_b) ⇒ Object

Compare two ids. This is useful to ensure we perform array operations in the right order.

compareIds(‘a.20.a’, ‘a.1.b’) => 1 (because 1 < 20) compareIds(‘a.0.a’, ‘b.1.b’) => -1 (because ‘a’ < ‘b’)



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 110

def compare_ids(id_a, id_b)
  parts_a = id_a.split('.')
  parts_b = id_b.split('.')
  length = [parts_a.length, parts_b.length].min

  (0...length).each do |i|
    # if both parts are numbers, we compare them numerically
    result = if parts_a[i] =~ /^\d+$/ && parts_b[i] =~ /^\d+$/
               parts_a[i].to_i <=> parts_b[i].to_i
             else
               # else, we compare as strings
               parts_a[i] <=> parts_b[i]
             end
    return result unless result.zero?
  end

  parts_a.length <=> parts_b.length
end

#deep_merge(target, source) ⇒ Object



93
94
95
96
97
98
99
100
101
102
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 93

def deep_merge(target, source)
  source.each do |key, value|
    if target[key].is_a?(Hash) && value.is_a?(Hash)
      deep_merge(target[key], value)
    else
      target[key] ||= value
    end
  end
  target
end

#escape(str) ⇒ Object



11
12
13
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 11

def escape(str)
  str.tr('.', '_')
end

#group_ids_by_path(ids) ⇒ Object



139
140
141
142
143
144
145
146
147
148
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 139

def group_ids_by_path(ids)
  updates = Hash.new { |hash, key| hash[key] = [] }

  ids.each do |id|
    root_id, path = split_id(id)
    updates[path] << root_id
  end

  updates
end

#recursive_delete(target, path) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 27

def recursive_delete(target, path)
  index = path.index('.')

  if index.nil?
    target.delete(path)
  else
    prefix = path[0..(index - 1)]
    suffix = path[(index + 1)..]

    if target.is_a?(Hash) && target.key?(prefix)
      recursive_delete(target[prefix], suffix)
      target.delete(prefix) if target[prefix].empty?
    end
  end
end

#recursive_set(target, path, value) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 15

def recursive_set(target, path, value)
  index = path.index('.')
  if index.nil?
    target[path] = value
  else
    prefix = path[0, index]
    suffix = path[index + 1, path.length]
    target[prefix] ||= {}
    recursive_set(target[prefix], suffix, value)
  end
end

#reformat_patch(patch) ⇒ Object



82
83
84
85
86
87
88
89
90
91
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 82

def reformat_patch(patch)
  patch.each_with_object({}) do |(key, value), result|
    keys = key.split('.')
    last_key = keys.pop
    nested_hash = keys.reverse.inject({ last_key => value }) do |hash, k|
      { k => hash }
    end
    deep_merge(result, nested_hash)
  end
end

#replace_mongo_types(data) ⇒ Object

not sure it this method is relevant for mongoid



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 44

def replace_mongo_types(data)
  case data
  when BSON::ObjectId, BSON::Decimal128
    data.to_s
  when Date, Time
    data.iso8601
  when Array
    data.map { |item| replace_mongo_types(item) }
  when Hash
    data.transform_values { |value| replace_mongo_types(value) }
  else
    data
  end
end

#split_id(id) ⇒ Object



129
130
131
132
133
134
135
136
137
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 129

def split_id(id)
  dot_index = id.index('.')
  root_id = id[0...dot_index]
  path = id[(dot_index + 1)..]

  root_id = BSON::ObjectId.from_string(root_id) if BSON::ObjectId.legal?(root_id)

  [root_id, path]
end

#unflatten_record(record, as_fields, patch_mode: false) ⇒ Object

Unflattend patches and records



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 60

def unflatten_record(record, as_fields, patch_mode: false)
  new_record = record.dup

  as_fields.each do |field|
    alias_field = field.gsub('.', '@@@')

    value = new_record[alias_field]

    next if value.nil?

    if patch_mode
      new_record[field] = value
    else
      recursive_set(new_record, field, value)
    end

    new_record.delete(alias_field)
  end

  new_record
end

#unnest(strings, prefix) ⇒ Object

Similar to projection.unnest unnest([‘firstname’, ‘book.title’, ‘book.author’], ‘book’) == [‘title’, ‘author’]



7
8
9
# File 'lib/forest_admin_datasource_mongoid/utils/helpers.rb', line 7

def unnest(strings, prefix)
  strings.select { |field| field.start_with?("#{prefix}.") }.map { |field| field[(prefix.size + 1)..] }
end