acts_as_sane_tree 1.0 → 1.1
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.
- data/CHANGELOG.rdoc +6 -0
- data/README.rdoc +7 -2
- data/acts_as_sane_tree.gemspec +1 -0
- data/lib/acts_as_sane_tree.rb +51 -40
- data/lib/version.rb +1 -1
- metadata +4 -3
data/CHANGELOG.rdoc
ADDED
data/README.rdoc
CHANGED
@@ -22,8 +22,13 @@ A few extras are provided. Of note are:
|
|
22
22
|
|
23
23
|
* #depth -> depth from root of the current node
|
24
24
|
* #descendents -> all descendents of the current node (provided in either flat array or nested hash)
|
25
|
-
* nodes_within?
|
26
|
-
* nodes_within
|
25
|
+
* nodes_within?(src, chk) - Returns true if chk contains any nodes found within src and all ancestors of nodes within src
|
26
|
+
* nodes_within(src, chk) - Returns any matching nodes from chk found within src and all ancestors within src
|
27
|
+
* nodes_and_descendents(*args) - Returns all nodes and descendents for given IDs or records.
|
28
|
+
|
29
|
+
== Documentation
|
30
|
+
|
31
|
+
http://chrisroberts.github.com/acts_as_sane_tree
|
27
32
|
|
28
33
|
== Thanks
|
29
34
|
|
data/acts_as_sane_tree.gemspec
CHANGED
data/lib/acts_as_sane_tree.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module ActsAsSaneTree
|
2
|
-
|
2
|
+
|
3
|
+
def self.included(base) # :nodoc:
|
3
4
|
base.extend(ClassMethods)
|
4
5
|
end
|
5
6
|
|
@@ -25,13 +26,14 @@ module ActsAsSaneTree
|
|
25
26
|
# root.children # => [child1]
|
26
27
|
# root.children.first.children.first # => subchild1
|
27
28
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# * <tt>
|
31
|
-
# * <tt>
|
32
|
-
# * <tt>
|
33
|
-
#
|
34
|
-
#
|
29
|
+
# The following class methods are also added:
|
30
|
+
#
|
31
|
+
# * <tt>nodes_within?(src, chk)</tt> - Returns true if chk contains any nodes found within src and all ancestors of nodes within src
|
32
|
+
# * <tt>nodes_within(src, chk)</tt> - Returns any matching nodes from chk found within src and all ancestors within src
|
33
|
+
# * <tt>nodes_and_descendents(*args)</tt> - Returns all nodes and descendents for given IDs or records. Accepts multiple IDs and records. Valid options:
|
34
|
+
# * :raw - No Hash nesting
|
35
|
+
# * :no_self - Will not return given nodes in result set
|
36
|
+
# * {:depth => n} - Will set maximum depth to query
|
35
37
|
module ClassMethods
|
36
38
|
# Configuration options are:
|
37
39
|
#
|
@@ -88,6 +90,40 @@ module ActsAsSaneTree
|
|
88
90
|
)
|
89
91
|
end
|
90
92
|
end
|
93
|
+
|
94
|
+
def self.nodes_and_descendents(*args)
|
95
|
+
raw = args.delete(:raw)
|
96
|
+
no_self = args.delete(:no_self)
|
97
|
+
depth = args.detect{|x|x.is_a?(Hash)}
|
98
|
+
if(depth)
|
99
|
+
args.delete(depth)
|
100
|
+
depth = depth[:depth]
|
101
|
+
end
|
102
|
+
base_ids = args.map{|x| x.is_a?(ActiveRecord::Base) ? x.id : x.to_i}
|
103
|
+
q = self.find_by_sql(
|
104
|
+
"WITH RECURSIVE crumbs AS (
|
105
|
+
SELECT #{self.table_name}.*, \#{no_self ? -1 : 0} AS level FROM #{self.table_name} WHERE id in (\#{base_ids.join(', ')})
|
106
|
+
UNION ALL
|
107
|
+
SELECT alias1.*, crumbs.level + 1 FROM crumbs JOIN #{self.table_name} alias1 on alias1.parent_id = crumbs.id
|
108
|
+
\#{depth ? "WHERE crumbs.level + 1 < \#{depth.to_i}" : ''}
|
109
|
+
) SELECT * FROM crumbs WHERE level >= 0 ORDER BY level, parent_id ASC"
|
110
|
+
)
|
111
|
+
unless(raw)
|
112
|
+
res = {}
|
113
|
+
cache = {}
|
114
|
+
q.each do |item|
|
115
|
+
cache[item.id] = {}
|
116
|
+
if(cache[item.parent_id])
|
117
|
+
cache[item.parent_id][item] = cache[item.id]
|
118
|
+
else
|
119
|
+
res[item] = cache[item.id]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
res
|
123
|
+
else
|
124
|
+
q
|
125
|
+
end
|
126
|
+
end
|
91
127
|
|
92
128
|
EOV
|
93
129
|
end
|
@@ -143,45 +179,20 @@ module ActsAsSaneTree
|
|
143
179
|
# \_ subchild2
|
144
180
|
# the resulting hash would look like:
|
145
181
|
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
182
|
+
# {child1 =>
|
183
|
+
# {subchild1 =>
|
184
|
+
# {subsubchild1 => {}},
|
185
|
+
# subchild2 => {}}}
|
150
186
|
#
|
151
187
|
# This method will accept two parameters.
|
152
188
|
# * :raw -> Result is flat array. No Hash tree is built
|
153
189
|
# * {:depth => n} -> Will only search for descendents to the given depth of n
|
154
190
|
def descendents(*args)
|
155
|
-
|
156
|
-
|
157
|
-
raw = args.include?(:raw)
|
158
|
-
q = self.class.find_by_sql(
|
159
|
-
"WITH RECURSIVE crumbs AS (
|
160
|
-
SELECT #{self.class.table_name}.*, -1 AS level FROM #{self.class.table_name} WHERE id = #{id}
|
161
|
-
UNION ALL
|
162
|
-
SELECT alias1.*, crumbs.level + 1 FROM crumbs JOIN #{self.class.table_name} alias1 on alias1.parent_id = crumbs.id
|
163
|
-
#{depth ? "WHERE crumbs.level + 1 < #{depth.to_i}" : ''}
|
164
|
-
) SELECT * FROM crumbs WHERE level >= 0 ORDER BY level, parent_id ASC"
|
165
|
-
)
|
166
|
-
unless(raw)
|
167
|
-
res = {}
|
168
|
-
cache = {}
|
169
|
-
q.each do |item|
|
170
|
-
cache[item.id] = {}
|
171
|
-
if(cache[item.parent_id])
|
172
|
-
cache[item.parent_id][item] = cache[item.id]
|
173
|
-
else
|
174
|
-
res[item] = cache[item.id]
|
175
|
-
end
|
176
|
-
end
|
177
|
-
res
|
178
|
-
else
|
179
|
-
q
|
180
|
-
end
|
191
|
+
args.delete_if{|x| !x.is_a?(Hash) && x != :raw}
|
192
|
+
self.class.nodes_and_descendents(:no_self, self, *args)
|
181
193
|
end
|
182
194
|
|
183
|
-
# Returns the depth of the current node. 0 depth represents the root
|
184
|
-
# of the tree
|
195
|
+
# Returns the depth of the current node. 0 depth represents the root of the tree
|
185
196
|
def depth
|
186
197
|
res = self.class.connection.select_all(
|
187
198
|
"WITH RECURSIVE crumbs AS (
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_sane_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: "1.
|
8
|
+
- 1
|
9
|
+
version: "1.1"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Chris Roberts
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- acts_as_sane_tree.gemspec
|
44
44
|
- init.rb
|
45
45
|
- README.rdoc
|
46
|
+
- CHANGELOG.rdoc
|
46
47
|
- lib/acts_as_sane_tree.rb
|
47
48
|
- lib/version.rb
|
48
49
|
has_rdoc: true
|