diff options
author | Bob Van Landuyt <bob@vanlanduyt.co> | 2017-10-04 16:56:42 +0200 |
---|---|---|
committer | Bob Van Landuyt <bob@vanlanduyt.co> | 2017-10-04 22:49:42 +0200 |
commit | 06e00913f505268e0a45f4f1516a93a84600c242 (patch) | |
tree | caa989d5a3a299cd1c1a1e6a13f90239ad1aed84 /app/models/concerns | |
parent | 08383fd2e32b88bba1429cf9b03b493dfc6b9b3e (diff) | |
download | gitlab-ce-06e00913f505268e0a45f4f1516a93a84600c242.tar.gz |
Move merging of Hashes out of the `GroupDescendant` concern
Since it can technically merge any hash with objects that respond to `==`
Diffstat (limited to 'app/models/concerns')
-rw-r--r-- | app/models/concerns/group_descendant.rb | 57 |
1 files changed, 4 insertions, 53 deletions
diff --git a/app/models/concerns/group_descendant.rb b/app/models/concerns/group_descendant.rb index 11f092db2ae..6c465079753 100644 --- a/app/models/concerns/group_descendant.rb +++ b/app/models/concerns/group_descendant.rb @@ -5,22 +5,18 @@ module GroupDescendant end def self.build_hierarchy(descendants, hierarchy_top = nil) - descendants = Array.wrap(descendants) + descendants = Array.wrap(descendants).uniq return [] if descendants.empty? unless descendants.all? { |hierarchy| hierarchy.is_a?(GroupDescendant) } raise ArgumentError.new('element is not a hierarchy') end - first_descendant, *other_descendants = descendants - merged = first_descendant.hierarchy(hierarchy_top, descendants) - - other_descendants.each do |descendant| - next_descendant = descendant.hierarchy(hierarchy_top, descendants) - merged = merge_hash_tree(merged, next_descendant) + all_hierarchies = descendants.map do |descendant| + descendant.hierarchy(hierarchy_top, descendants) end - merged + Gitlab::Utils::MergeHash.merge(all_hierarchies) end private @@ -50,49 +46,4 @@ module GroupDescendant hierarchy end end - - private_class_method def self.merge_hash_tree(first_child, second_child) - # When the first is an array, we need to go over every element to see if - # we can merge deeper. If no match is found, we add the element to the array - # - # Handled cases: - # [Array, Hash] - if first_child.is_a?(Array) && second_child.is_a?(Hash) - merge_hash_into_array(first_child, second_child) - elsif first_child.is_a?(Hash) && second_child.is_a?(Array) - merge_hash_into_array(second_child, first_child) - # If both of them are hashes, we can deep_merge with the same logic - # - # Handled cases: - # [Hash, Hash] - elsif first_child.is_a?(Hash) && second_child.is_a?(Hash) - first_child.deep_merge(second_child) { |key, first, second| merge_hash_tree(first, second) } - # If only one of them is a hash, and one of them is a GroupHierachy-object - # we can check if its already in the hash. If so, we don't need to do anything - # - # Handled cases - # [Hash, GroupDescendant] - elsif first_child.is_a?(Hash) && first_child.keys.include?(second_child) - first_child - elsif second_child.is_a?(Hash) && second_child.keys.include?(first_child) - second_child - # If one or both elements are a GroupDescendant, we wrap create an array - # combining them. - # - # Handled cases: - # [GroupDescendant, Array], [GroupDescendant, GroupDescendant], [Array, Array] - else - Array.wrap(first_child) + Array.wrap(second_child) - end - end - - private_class_method def self.merge_hash_into_array(array, new_hash) - if mergeable_index = array.index { |element| element.is_a?(Hash) && (element.keys & new_hash.keys).any? } - array[mergeable_index] = merge_hash_tree(array[mergeable_index], new_hash) - else - array << new_hash - end - - array - end end |