hierarchy-tree 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hierarchy_tree.rb +52 -22
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d4301de42dc78d8664798e551f846073a2bd7a79a2f5d5245d5c9e9339145c4
|
4
|
+
data.tar.gz: 73f7863eb9059605923a62c27dcc4baa3193509d5c0240f178e33f185e10df2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1567fd7d03e5e87ba9b8efe378a9ec15361352e9631229fa75b547905c762999d7315f4749841594aa2e1bd306a81f133d742f581fb76aa7dbe8523cf23754da
|
7
|
+
data.tar.gz: e371543dcc4e11f0946595218da4beaf1bb792b596988d16b417c5441d00f5d4e0492f2f740acaae869e83bd336c8a27de57161c86e7e448a56c28461b3f6070
|
data/lib/hierarchy_tree.rb
CHANGED
@@ -2,10 +2,10 @@ require 'active_record'
|
|
2
2
|
require 'active_support/core_ext/object/inclusion.rb'
|
3
3
|
|
4
4
|
################ Debug ################
|
5
|
-
# gem
|
6
|
-
# rm hierarchy-tree-
|
5
|
+
# gem cleanup hierarchy-tree
|
6
|
+
# rm hierarchy-tree-X.Y.Z.gem
|
7
7
|
# gem build hierarchy_tree
|
8
|
-
# gem install hierarchy-tree-
|
8
|
+
# gem install hierarchy-tree-X.Y.Z.gem
|
9
9
|
# ruby -Itest test/test_hierarchy_tree.rb
|
10
10
|
|
11
11
|
class Hierarchy
|
@@ -26,20 +26,34 @@ class Hierarchy
|
|
26
26
|
@classes_list
|
27
27
|
end
|
28
28
|
|
29
|
-
# Return the ancestors associations by navigating through :belongs_to
|
29
|
+
# Return all the possible ancestors associations by navigating through :belongs_to
|
30
30
|
# Starting from the "from" class towards the "to" class
|
31
|
-
|
32
|
-
|
33
|
-
return if from.to_s == to.to_s and descendants == [] # Base case
|
34
|
-
return 'loop' if from.in? descendants # Avoids cycle
|
31
|
+
def self.ancestors(from:, to:)
|
32
|
+
return [] if from.to_s == to.to_s
|
35
33
|
|
36
|
-
|
34
|
+
queue = [{ class: from.to_s, path: [] }]
|
35
|
+
visited = { from.to_s => [] }
|
36
|
+
paths = []
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
while queue.any?
|
39
|
+
current = queue.shift
|
40
|
+
current_class = current[:class]
|
41
|
+
current_path = current[:path]
|
42
|
+
|
43
|
+
current_class.constantize.reflect_on_all_associations(:belongs_to).each do |relation|
|
44
|
+
next_class = relation.klass.to_s
|
45
|
+
next_path = current_path + [relation.name]
|
46
|
+
|
47
|
+
paths << hashify(next_path) if next_class == to.to_s
|
48
|
+
|
49
|
+
if relation.class_name != from.name and next_path == next_path.uniq # Non-looped path
|
50
|
+
visited[next_class] = next_path
|
51
|
+
queue.push({ class: next_class, path: next_path })
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
paths
|
43
57
|
end
|
44
58
|
|
45
59
|
# Return the ancestors associations by navigating through :belongs_to
|
@@ -70,6 +84,22 @@ class Hierarchy
|
|
70
84
|
end
|
71
85
|
end
|
72
86
|
|
87
|
+
# Return the ancestors associations by navigating through :belongs_to
|
88
|
+
# Starting from the "from" class towards the "to" class
|
89
|
+
# Using DFS - Depth First Search, thus finding the Deepest Path (more likely)
|
90
|
+
def self.ancestors_dfs(from:, to:, descendants: [])
|
91
|
+
return if from.to_s == to.to_s and descendants == [] # Base case
|
92
|
+
return 'loop' if from.in? descendants # Avoids cycle
|
93
|
+
|
94
|
+
descendants.push(from)
|
95
|
+
|
96
|
+
from.reflect_on_all_associations(:belongs_to).map do |relation|
|
97
|
+
return relation.name if relation.klass.to_s == to.to_s # Path is found
|
98
|
+
path = ancestors_dfs(from: relation.klass, to: to, descendants: descendants)
|
99
|
+
return { relation.name => path } if valid_path?(path, to.model_name.param_key.to_sym)
|
100
|
+
end.compact.first
|
101
|
+
end
|
102
|
+
|
73
103
|
def self.loop?(klass)
|
74
104
|
@cache = {}
|
75
105
|
false if dfs_hierarchy(class: klass, classes?: false)
|
@@ -151,6 +181,14 @@ class Hierarchy
|
|
151
181
|
true
|
152
182
|
end
|
153
183
|
|
184
|
+
def self.hashify(array)
|
185
|
+
if array.length == 1
|
186
|
+
array.first
|
187
|
+
else
|
188
|
+
{ array.first => hashify(array.drop(1)) }
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
154
192
|
def self.valid_path?(path, target)
|
155
193
|
return true if path == target
|
156
194
|
|
@@ -163,12 +201,4 @@ class Hierarchy
|
|
163
201
|
false
|
164
202
|
end
|
165
203
|
end
|
166
|
-
|
167
|
-
def self.hashify(array)
|
168
|
-
if array.length == 1
|
169
|
-
array.first
|
170
|
-
else
|
171
|
-
{ array.first => hashify(array.drop(1)) }
|
172
|
-
end
|
173
|
-
end
|
174
204
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hierarchy-tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Cordeiro Costa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|