acts_as_sane_tree 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|