closure_tree 1.0.0.beta2 → 1.0.0.beta3
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/README.rdoc +5 -5
- data/lib/closure_tree/acts_as_tree.rb +32 -26
- data/lib/closure_tree/version.rb +1 -1
- data/test/dummy/db/migrate/20110522004834_create_tags.rb +1 -0
- data/test/dummy/db/schema.rb +1 -0
- data/test/dummy/test/fixtures/tags.yml +3 -1
- data/test/dummy/test/unit/tag_test.rb +11 -5
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -79,17 +79,17 @@ Then:
|
|
79
79
|
puts grandparent.self_and_descendants.collect{ |t| t.name }.join(" > ")
|
80
80
|
"grandparent > parent > child"
|
81
81
|
|
82
|
-
child.
|
82
|
+
child.ancestry_path
|
83
83
|
["grandparent", "parent", "child"]
|
84
84
|
|
85
85
|
=== <code>find_or_create_by_path</code>
|
86
86
|
|
87
|
-
|
88
|
-
|
87
|
+
We can do all the node creation and add_child calls from the prior section with one method call:
|
88
|
+
child = Tag.find_or_create_by_path "grandparent", "parent", "child"
|
89
89
|
|
90
|
-
|
90
|
+
You can <code>find</code> as well as <code>find_or_create</code> by "ancestry paths". Ancestry paths may be built using any column in your model. The default column is <code>name</code>, which can be changed with the :name_column option provided to <code>acts_as_tree</code>.
|
91
91
|
|
92
|
-
|
92
|
+
Note that the other columns will be null if nodes are created, other than auto-generated columns like ID and created_at timestamp. Only the specified column will receive the path element value.
|
93
93
|
|
94
94
|
== Accessing Data
|
95
95
|
|
@@ -91,10 +91,11 @@ module ClosureTree #:nodoc:
|
|
91
91
|
[self].concat ancestors.to_a
|
92
92
|
end
|
93
93
|
|
94
|
-
# Returns an array, root first, of self_and_ancestors' +
|
95
|
-
#
|
96
|
-
|
97
|
-
|
94
|
+
# Returns an array, root first, of self_and_ancestors' values of the +to_s_column+, which defaults
|
95
|
+
# to the +name_column+.
|
96
|
+
# (so child.ancestry_path == +%w{grandparent parent child}+
|
97
|
+
def ancestry_path to_s_column = name_column
|
98
|
+
self_and_ancestors.reverse.collect { |n| n.send to_s_column.to_sym }
|
98
99
|
end
|
99
100
|
|
100
101
|
def self_and_descendants
|
@@ -128,22 +129,25 @@ module ClosureTree #:nodoc:
|
|
128
129
|
new_parent.add_child self
|
129
130
|
end
|
130
131
|
|
131
|
-
# Find a child node whose +
|
132
|
-
|
133
|
-
|
132
|
+
# Find a child node whose +ancestry_path+ minus self.ancestry_path is +path+.
|
133
|
+
# If the first argument is a symbol, it will be used as the column to search by
|
134
|
+
def find_by_path *path
|
135
|
+
_find_or_create_by_path "find", path
|
134
136
|
end
|
135
137
|
|
136
|
-
# Find a child node whose +
|
137
|
-
def find_or_create_by_path path
|
138
|
-
_find_or_create_by_path
|
138
|
+
# Find a child node whose +ancestry_path+ minus self.ancestry_path is +path+
|
139
|
+
def find_or_create_by_path *path
|
140
|
+
_find_or_create_by_path "find_or_create", path
|
139
141
|
end
|
140
142
|
|
141
143
|
protected
|
142
144
|
|
143
|
-
def _find_or_create_by_path
|
145
|
+
def _find_or_create_by_path method_prefix, path
|
146
|
+
to_s_column = path.first.is_a?(Symbol) ? path.shift.to_s : name_column
|
147
|
+
path.flatten!
|
144
148
|
node = self
|
145
|
-
while (
|
146
|
-
node = node.children.send(
|
149
|
+
while (s = path.shift and node)
|
150
|
+
node = node.children.send("#{method_prefix}_by_#{to_s_column}".to_sym, s)
|
147
151
|
end
|
148
152
|
node
|
149
153
|
end
|
@@ -170,27 +174,29 @@ module ClosureTree #:nodoc:
|
|
170
174
|
nil
|
171
175
|
end
|
172
176
|
|
173
|
-
# Find the node whose +
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
+
# Find the node whose +ancestry_path+ is +path+
|
178
|
+
# If the first argument is a symbol, it will be used as the column to search by
|
179
|
+
def find_by_path *path
|
180
|
+
to_s_column = path.first.is_a?(Symbol) ? path.shift.to_s : name_column
|
181
|
+
path.flatten!
|
182
|
+
self.where(to_s_column => path.last).each do |n|
|
183
|
+
return n if path == n.ancestry_path(to_s_column)
|
177
184
|
end
|
178
185
|
nil
|
179
186
|
end
|
180
187
|
|
181
|
-
# Find or create nodes such that the +
|
182
|
-
def find_or_create_by_path path
|
188
|
+
# Find or create nodes such that the +ancestry_path+ is +path+
|
189
|
+
def find_or_create_by_path *path
|
183
190
|
# short-circuit if we can:
|
184
191
|
n = find_by_path path
|
185
192
|
return n if n
|
186
193
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
node
|
194
|
+
column_sym = path.first.is_a?(Symbol) ? path.shift : name_sym
|
195
|
+
path.flatten!
|
196
|
+
s = path.shift
|
197
|
+
node = roots.where(column_sym => s).first
|
198
|
+
node = create!(column_sym => s) unless node
|
199
|
+
node.find_or_create_by_path column_sym, path
|
194
200
|
end
|
195
201
|
|
196
202
|
private
|
data/lib/closure_tree/version.rb
CHANGED
data/test/dummy/db/schema.rb
CHANGED
@@ -57,26 +57,32 @@ class TagTest < ActiveSupport::TestCase
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def test_ancestry_path
|
60
|
-
assert_equal %w{grandparent parent child}, tags(:child).
|
60
|
+
assert_equal %w{grandparent parent child}, tags(:child).ancestry_path
|
61
|
+
assert_equal %w{grandparent parent child}, tags(:child).ancestry_path(:name)
|
62
|
+
assert_equal %w{Nonnie Mom Kid}, tags(:child).ancestry_path(:title)
|
61
63
|
end
|
62
64
|
|
63
65
|
def test_find_by_path
|
64
66
|
# class method:
|
65
67
|
assert_equal tags(:child), Tag.find_by_path(%w{grandparent parent child})
|
66
|
-
assert_equal tags(:child), Tag.
|
68
|
+
assert_equal tags(:child), Tag.find_by_path(:title, %w{Nonnie Mom Kid})
|
67
69
|
# instance method:
|
68
70
|
assert_equal tags(:child), tags(:parent).find_by_path(%w{child})
|
71
|
+
assert_equal tags(:child), tags(:parent).find_by_path(:title, %w{Kid})
|
69
72
|
assert_equal tags(:child), tags(:grandparent).find_by_path(%w{parent child})
|
73
|
+
assert_equal tags(:child), tags(:grandparent).find_by_path(:title, %w{Mom Kid})
|
70
74
|
assert_nil tags(:parent).find_by_path(%w{child larvae})
|
71
75
|
end
|
72
76
|
|
73
77
|
def test_find_or_create_by_path
|
74
78
|
# class method:
|
75
|
-
assert_equal
|
79
|
+
assert_equal tags(:child), Tag.find_or_create_by_path(%w{grandparent parent child})
|
80
|
+
assert_equal tags(:child), Tag.find_or_create_by_path(:title, %w{Nonnie Mom Kid})
|
81
|
+
assert_equal %w{events anniversary}, Tag.find_or_create_by_path(%w{events anniversary}).ancestry_path
|
76
82
|
a = Tag.find_or_create_by_path(%w{a})
|
77
|
-
assert_equal %w{a}, a.
|
83
|
+
assert_equal %w{a}, a.ancestry_path
|
78
84
|
# instance method:
|
79
|
-
assert_equal %w{a b c}, a.find_or_create_by_path(%w{b c}).
|
85
|
+
assert_equal %w{a b c}, a.find_or_create_by_path(%w{b c}).ancestry_path
|
80
86
|
end
|
81
87
|
|
82
88
|
def test_descendants
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: closure_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 1.0.0.
|
5
|
+
version: 1.0.0.beta3
|
6
6
|
platform: ruby
|
7
7
|
authors: []
|
8
8
|
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-26 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -73,7 +73,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
73
|
requirements:
|
74
74
|
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
hash:
|
76
|
+
hash: 2257595380188246970
|
77
77
|
segments:
|
78
78
|
- 0
|
79
79
|
version: "0"
|