treeify 0.01 → 0.02
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/treeify.rb +38 -23
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c05d601b25f5e493f430b1ae5354410f237ae90
|
4
|
+
data.tar.gz: 28c555a605c4b17e542127398ea4feee6da00216
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eabf4eca128f87d7c3034021e40ddbb9ba752ee826be1a73a53552079a4dbac4516cd2df0cc60c96688f4de0030fe7002f1e3abd2b7211e17cf78d4bc318e786
|
7
|
+
data.tar.gz: f2653463b3f9d161136447b3f827ff9105a0cb90e1cde341defe34c93028214323791c8ec272c87cd9e771e6c45b9e0d75e5c08a94fafc1ab262a86386f77208
|
data/lib/treeify.rb
CHANGED
@@ -6,42 +6,57 @@ require "active_support/core_ext/class/attribute"
|
|
6
6
|
module Treeify
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
+
included do
|
10
|
+
class_attribute :cols
|
11
|
+
scope :roots, -> { where(parent_id: nil) }
|
12
|
+
scope :tree_for, ->(instance) { where("#{table_name}.id IN (#{tree_sql_for(instance)})").order("#{table_name}.id") }
|
13
|
+
scope :tree_for_ancestors, ->(instance) { where("#{table_name}.id IN (#{tree_sql_for_ancestors(instance)})").order("#{table_name}.id") }
|
14
|
+
end
|
15
|
+
|
9
16
|
module ClassMethods
|
10
|
-
mattr_accessor :table_name
|
11
|
-
mattr_accessor :cols
|
12
17
|
|
13
18
|
def config(hash = {})
|
14
19
|
# apparently columns is a reserved word in rails
|
15
20
|
self.cols = hash[:cols]
|
16
|
-
self.table_name = hash[:table_name]
|
17
21
|
end
|
18
22
|
|
19
|
-
def
|
20
|
-
"WITH RECURSIVE cte (id,
|
23
|
+
def tree_sql(instance)
|
24
|
+
"WITH RECURSIVE cte (id, path) AS (
|
21
25
|
SELECT id,
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
1 AS depth
|
26
|
-
FROM #{self.table_name}
|
27
|
-
WHERE parent_id IS NULL
|
26
|
+
array[id] AS path
|
27
|
+
FROM #{table_name}
|
28
|
+
WHERE id = #{instance.id}
|
28
29
|
|
29
30
|
UNION ALL
|
30
31
|
|
31
|
-
SELECT #{
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
cte.depth + 1 AS depth
|
37
|
-
FROM #{self.table_name}
|
38
|
-
JOIN cte ON #{self.table_name}.parent_id = cte.id
|
39
|
-
)
|
40
|
-
SELECT id, #{self.cols.join(',')}, path, depth FROM cte
|
41
|
-
ORDER BY path;"
|
32
|
+
SELECT #{table_name}.id,
|
33
|
+
cte.path || #{table_name}.id
|
34
|
+
FROM #{table_name}
|
35
|
+
JOIN cte ON #{table_name}.parent_id = cte.id
|
36
|
+
)"
|
42
37
|
end
|
38
|
+
|
39
|
+
def tree_sql_for(instance)
|
40
|
+
"#{tree_sql(instance)}
|
41
|
+
SELECT id FROM cte
|
42
|
+
ORDER BY path"
|
43
|
+
end
|
44
|
+
|
45
|
+
def tree_sql_for_ancestors(instance)
|
46
|
+
"#{tree_sql(instance)}
|
47
|
+
SELECT cte.id FROM cte WHERE cte.id != #{instance.id}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def descendents
|
52
|
+
self_and_descendents - [self]
|
53
|
+
end
|
54
|
+
|
55
|
+
def ancestors
|
56
|
+
self.class.tree_for_ancestors(self)
|
43
57
|
end
|
44
58
|
|
45
|
-
|
59
|
+
def self_and_descendents
|
60
|
+
self.class.tree_for(self)
|
46
61
|
end
|
47
62
|
end
|