closure_tree 3.2.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +8 -0
- data/lib/closure_tree/acts_as_tree.rb +19 -4
- data/lib/closure_tree/version.rb +1 -1
- data/spec/db/schema.rb +4 -0
- data/spec/support/models.rb +11 -0
- data/spec/user_spec.rb +11 -0
- metadata +3 -3
data/README.md
CHANGED
@@ -178,10 +178,13 @@ When you include ```acts_as_tree``` in your model, you can provide a hash to ove
|
|
178
178
|
* ```tag.parent``` returns the node's immediate parent. Root nodes will return nil.
|
179
179
|
* ```tag.children``` is a ```has_many``` of immediate children (just those nodes whose parent is the current node).
|
180
180
|
* ```tag.ancestors``` is a ordered scope of [ parent, grandparent, great grandparent, … ]. Note that the size of this array will always equal ```tag.depth```.
|
181
|
+
* ```tag.ancestor_ids``` is an array of the IDs of the ancestors.
|
181
182
|
* ```tag.self_and_ancestors``` returns a scope containing self, parent, grandparent, great grandparent, etc.
|
182
183
|
* ```tag.siblings``` returns a scope containing all nodes with the same parent as ```tag```, excluding self.
|
184
|
+
* ```tag.sibling_ids``` returns an array of the IDs of the siblings.
|
183
185
|
* ```tag.self_and_siblings``` returns a scope containing all nodes with the same parent as ```tag```, including self.
|
184
186
|
* ```tag.descendants``` returns a scope of all children, childrens' children, etc., excluding self ordered by depth.
|
187
|
+
* ```tag.descendant_ids``` returns an array of the IDs of the descendants.
|
185
188
|
* ```tag.self_and_descendants``` returns a scope of all children, childrens' children, etc., including self, ordered by depth.
|
186
189
|
* ```tag.destroy``` will destroy a node and do <em>something</em> to its children, which is determined by the ```:dependent``` option passed to ```acts_as_tree```.
|
187
190
|
|
@@ -282,6 +285,11 @@ Closure tree is [tested under every combination](https://secure.travis-ci.org/mc
|
|
282
285
|
|
283
286
|
## Change log
|
284
287
|
|
288
|
+
### 3.2.1
|
289
|
+
|
290
|
+
* Added ```ancestor_ids```, ```descendant_ids```, and ```sibling_ids```
|
291
|
+
* Added example spec to solve [issue 9](https://github.com/mceachen/closure_tree/issues/9)
|
292
|
+
|
285
293
|
### 3.2.0
|
286
294
|
|
287
295
|
* Added support for deterministic ordering of nodes.
|
@@ -136,6 +136,10 @@ module ClosureTree
|
|
136
136
|
without_self(self_and_ancestors)
|
137
137
|
end
|
138
138
|
|
139
|
+
def ancestor_ids
|
140
|
+
ids_from(ancestors)
|
141
|
+
end
|
142
|
+
|
139
143
|
# Returns an array, root first, of self_and_ancestors' values of the +to_s_column+, which defaults
|
140
144
|
# to the +name_column+.
|
141
145
|
# (so child.ancestry_path == +%w{grandparent parent child}+
|
@@ -147,6 +151,10 @@ module ClosureTree
|
|
147
151
|
without_self(self_and_descendants)
|
148
152
|
end
|
149
153
|
|
154
|
+
def descendant_ids
|
155
|
+
ids_from(descendants)
|
156
|
+
end
|
157
|
+
|
150
158
|
def self_and_siblings
|
151
159
|
s = self.class.scoped.where(:parent_id => parent)
|
152
160
|
quoted_order_column ? s.order(quoted_order_column) : s
|
@@ -156,6 +164,10 @@ module ClosureTree
|
|
156
164
|
without_self(self_and_siblings)
|
157
165
|
end
|
158
166
|
|
167
|
+
def sibling_ids
|
168
|
+
ids_from(siblings)
|
169
|
+
end
|
170
|
+
|
159
171
|
# Alias for appending to the children collection.
|
160
172
|
# You can also add directly to the children collection, if you'd prefer.
|
161
173
|
def add_child(child_node)
|
@@ -252,8 +264,12 @@ module ClosureTree
|
|
252
264
|
scope.where(["#{quoted_table_name}.#{self.class.primary_key} != ?", self])
|
253
265
|
end
|
254
266
|
|
267
|
+
def ids_from(scope)
|
268
|
+
scope.select(:id).collect(&:id)
|
269
|
+
end
|
270
|
+
|
255
271
|
def ct_parent_id
|
256
|
-
|
272
|
+
read_attribute(parent_column_sym)
|
257
273
|
end
|
258
274
|
|
259
275
|
# TODO: _parent_id will be removed in the next major version
|
@@ -393,12 +409,11 @@ module ClosureTree
|
|
393
409
|
end
|
394
410
|
|
395
411
|
def order_value
|
396
|
-
|
412
|
+
read_attribute(order_column_sym)
|
397
413
|
end
|
398
414
|
|
399
415
|
def order_value=(new_order_value)
|
400
|
-
|
401
|
-
send("#{order_column}=".to_sym, new_order_value)
|
416
|
+
write_attribute(order_column_sym, new_order_value)
|
402
417
|
end
|
403
418
|
|
404
419
|
def quoted_order_column(include_table_name = true)
|
data/lib/closure_tree/version.rb
CHANGED
data/spec/db/schema.rb
CHANGED
@@ -30,6 +30,10 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
30
30
|
t.datetime "updated_at"
|
31
31
|
end
|
32
32
|
|
33
|
+
create_table "contracts", :force => true do |t|
|
34
|
+
t.integer "user_id", :null => false
|
35
|
+
end
|
36
|
+
|
33
37
|
create_table "referral_hierarchies", :id => false, :force => true do |t|
|
34
38
|
t.integer "ancestor_id", :null => false
|
35
39
|
t.integer "descendant_id", :null => false
|
data/spec/support/models.rb
CHANGED
@@ -21,6 +21,13 @@ class User < ActiveRecord::Base
|
|
21
21
|
acts_as_tree :parent_column_name => "referrer_id",
|
22
22
|
:name_column => 'email',
|
23
23
|
:hierarchy_table_name => 'referral_hierarchies'
|
24
|
+
|
25
|
+
has_many :contracts
|
26
|
+
|
27
|
+
def indirect_contracts
|
28
|
+
Contract.where(:user_id => descendant_ids)
|
29
|
+
end
|
30
|
+
|
24
31
|
attr_accessible :email, :referrer
|
25
32
|
|
26
33
|
def to_s
|
@@ -28,6 +35,10 @@ class User < ActiveRecord::Base
|
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
38
|
+
class Contract < ActiveRecord::Base
|
39
|
+
belongs_to :user
|
40
|
+
end
|
41
|
+
|
31
42
|
class Label < ActiveRecord::Base
|
32
43
|
acts_as_tree :order => "sort_order"
|
33
44
|
attr_accessible :name
|
data/spec/user_spec.rb
CHANGED
@@ -75,4 +75,15 @@ describe "empty db" do
|
|
75
75
|
User.leaves.should == [@leaf]
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
it "supports users with contracts" do
|
80
|
+
u = User.find_or_create_by_path(%w(a@t.co b@t.co c@t.co))
|
81
|
+
u.descendant_ids.should == []
|
82
|
+
u.ancestor_ids.should == [u.parent.id, u.root.id]
|
83
|
+
u.root.descendant_ids.should == [u.parent.id, u.id]
|
84
|
+
u.root.ancestor_ids.should == []
|
85
|
+
c1 = u.contracts.create!
|
86
|
+
c2 = u.parent.contracts.create!
|
87
|
+
u.root.indirect_contracts.to_a.should =~ [c1, c2]
|
88
|
+
end
|
78
89
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: closure_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -193,7 +193,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
193
193
|
version: '0'
|
194
194
|
segments:
|
195
195
|
- 0
|
196
|
-
hash: -
|
196
|
+
hash: -1184203510025686599
|
197
197
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
198
|
none: false
|
199
199
|
requirements:
|
@@ -202,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
202
|
version: '0'
|
203
203
|
segments:
|
204
204
|
- 0
|
205
|
-
hash: -
|
205
|
+
hash: -1184203510025686599
|
206
206
|
requirements: []
|
207
207
|
rubyforge_project:
|
208
208
|
rubygems_version: 1.8.21
|