closure_tree 3.2.0 → 3.2.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/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
|