closure_tree 3.8.2 → 3.9.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA512:
3
+ metadata.gz: 4eba6a7034297fd15958c27428782adc3a1b36abc1f0723039583418c33eb08377e3b5cfa744aae985cdd2b1b2cbd91138486e2a0591c0ff2f9c1fcb9893361d
4
+ data.tar.gz: 8f8f339d462f846bfb59c260756d94ad8328a9bea1f4bf9ad2d9d00317f05efd7f8d099eee2b1c1a8e661ccef827fcbb46cb9f5a22f9e0f816bd5b8118fea9c4
5
+ SHA1:
6
+ metadata.gz: f04e325774ddd75fddfaeb47753095903350aed8
7
+ data.tar.gz: 66ed5c26efe5cac30d3bb3e3d1d128ae67d4e184
data/README.md CHANGED
@@ -15,8 +15,8 @@ closure_tree has some great features:
15
15
  * Fetch your whole ancestor lineage in 1 SELECT.
16
16
  * Grab all your descendants in 1 SELECT.
17
17
  * Get all your siblings in 1 SELECT.
18
- * Fetch all [7-degrees-of-bacon in a nested hash](#nested-hashes) in 1 SELECT.
19
- * [Find a node by path](#find_or_create_by_path) in 1 SELECT.
18
+ * Fetch all [descendants as a nested hash](#nested-hashes) in 1 SELECT.
19
+ * [Find a node by ancestry path](#find_or_create_by_path) in 1 SELECT.
20
20
  * __Best-in-class mutation performance__:
21
21
  * 2 SQL INSERTs on node creation
22
22
  * 3 SQL INSERT/UPDATEs on node reparenting
@@ -26,7 +26,6 @@ closure_tree has some great features:
26
26
  * ```find_or_create_by_path``` for [building out hierarchies quickly and conveniently](#find_or_create_by_path)
27
27
  * Support for [deterministic ordering](#deterministic-ordering) of children
28
28
  * Support for [preordered](http://en.wikipedia.org/wiki/Tree_traversal#Pre-order) traversal of descendants
29
- * Support for single-select depth-limited [nested hashes](#nested-hashes)
30
29
  * Excellent [test coverage](#testing) in a variety of environments
31
30
 
32
31
  See [Bill Karwin](http://karwin.blogspot.com/)'s excellent
@@ -115,12 +114,6 @@ Child nodes are created by appending to the children collection:
115
114
  parent = grandparent.children.create(:name => 'Parent')
116
115
  ```
117
116
 
118
- Or by giving the parent to the constructor:
119
-
120
- ```ruby
121
- child1 = Tag.create(:name => 'First Child', :parent => parent)
122
- ```
123
-
124
117
  Or by appending to the children collection:
125
118
 
126
119
  ```ruby
@@ -250,6 +243,7 @@ When you include ```acts_as_tree``` in your model, you can provide a hash to ove
250
243
  * ```tag.depth``` returns the depth, or "generation", for this node in the tree. A root node will have a value of 0.
251
244
  * ```tag.parent``` returns the node's immediate parent. Root nodes will return nil.
252
245
  * ```tag.children``` is a ```has_many``` of immediate children (just those nodes whose parent is the current node).
246
+ * ```tag.child_ids``` is an array of the IDs of the children.
253
247
  * ```tag.ancestors``` is a ordered scope of [ parent, grandparent, great grandparent, … ]. Note that the size of this array will always equal ```tag.depth```.
254
248
  * ```tag.ancestor_ids``` is an array of the IDs of the ancestors.
255
249
  * ```tag.self_and_ancestors``` returns a scope containing self, parent, grandparent, great grandparent, etc.
@@ -426,6 +420,16 @@ Parallelism is not tested with Rails 3.0.x nor 3.1.x due to this
426
420
 
427
421
  ## Change log
428
422
 
423
+ ### 3.9.0
424
+
425
+ * Added ```.child_ids```.
426
+ * Removed ```dependent => destroy``` on the descendant_hierarchy and ancestor_hierarchy collections
427
+ (they were a mistake).
428
+ * Clarified documentation for creation and child associations.
429
+ Because ```Tag.create!(:parent => ...)``` requires a ```.reload```, I removed it as an example.
430
+
431
+ All three of these improvements were suggested by Andrew Bromwich. Thanks!
432
+
429
433
  ### 3.8.2
430
434
 
431
435
  * find_by_path uses 1 SELECT now. BOOM.
@@ -27,8 +27,7 @@ module ClosureTree
27
27
  has_many :ancestor_hierarchies,
28
28
  :class_name => hierarchy_class_name,
29
29
  :foreign_key => "descendant_id",
30
- :order => "#{quoted_hierarchy_table_name}.generations asc",
31
- :dependent => :destroy
30
+ :order => "#{quoted_hierarchy_table_name}.generations asc"
32
31
 
33
32
  has_many :self_and_ancestors,
34
33
  :through => :ancestor_hierarchies,
@@ -38,8 +37,7 @@ module ClosureTree
38
37
  has_many :descendant_hierarchies,
39
38
  :class_name => hierarchy_class_name,
40
39
  :foreign_key => "ancestor_id",
41
- :order => "#{quoted_hierarchy_table_name}.generations asc",
42
- :dependent => :destroy
40
+ :order => "#{quoted_hierarchy_table_name}.generations asc"
43
41
  # TODO: FIXME: this collection currently ignores sort_order
44
42
  # (because the quoted_table_named would need to be joined in to get to the order column)
45
43
 
@@ -94,6 +92,10 @@ module ClosureTree
94
92
  self_and_ancestors.reverse.collect { |n| n.send to_s_column.to_sym }
95
93
  end
96
94
 
95
+ def child_ids
96
+ ids_from(children)
97
+ end
98
+
97
99
  def descendants
98
100
  without_self(self_and_descendants)
99
101
  end
@@ -1,3 +1,3 @@
1
1
  module ClosureTree
2
- VERSION = "3.8.2" unless defined?(::ClosureTree::VERSION)
2
+ VERSION = "3.9.0" unless defined?(::ClosureTree::VERSION)
3
3
  end
data/spec/label_spec.rb CHANGED
@@ -43,6 +43,19 @@ def create_preorder_tree
43
43
  end
44
44
 
45
45
  describe Label do
46
+
47
+ context "destruction" do
48
+ it "properly destroys descendents" do
49
+ c = Label.find_or_create_by_path %w(a b c)
50
+ b = c.parent
51
+ a = c.root
52
+ a.destroy
53
+ Label.exists?(a).should be_false
54
+ Label.exists?(b).should be_false
55
+ Label.exists?(c).should be_false
56
+ end
57
+ end
58
+
46
59
  context "Base Label class" do
47
60
  it "should find or create by path" do
48
61
  # class method:
@@ -44,7 +44,9 @@ end
44
44
 
45
45
  class Label < ActiveRecord::Base
46
46
  attr_accessible :name # < - make sure order doesn't matter
47
- acts_as_tree :order => "sort_order", :parent_column_name => "mother_id"
47
+ acts_as_tree :order => "sort_order",
48
+ :parent_column_name => "mother_id",
49
+ :dependent => :destroy
48
50
 
49
51
  def to_s
50
52
  "#{self.class}: #{name}"
data/spec/tag_spec.rb CHANGED
@@ -33,11 +33,19 @@ shared_examples_for "Tag (1)" do
33
33
  end
34
34
 
35
35
  context "2 tag db" do
36
+ before :each do
37
+ @root = Tag.create!(:name => "root")
38
+ @leaf = @root.add_child(Tag.create!(:name => "leaf"))
39
+ end
36
40
  it "should return a simple root and leaf" do
37
- root = Tag.create!(:name => "root")
38
- leaf = root.add_child(Tag.create!(:name => "leaf"))
39
- Tag.roots.should == [root]
40
- Tag.leaves.should == [leaf]
41
+ Tag.roots.should == [@root]
42
+ Tag.leaves.should == [@leaf]
43
+ end
44
+ it "should return child_ids for root" do
45
+ @root.child_ids.should == [@leaf.id]
46
+ end
47
+ it "should return an empty array for leaves" do
48
+ @leaf.child_ids.should be_empty
41
49
  end
42
50
  end
43
51
 
@@ -220,7 +228,6 @@ shared_examples_for "Tag (1)" do
220
228
  a.find_or_create_by_path(%w{b c}).ancestry_path.should == %w{a b c}
221
229
  end
222
230
  end
223
-
224
231
  end
225
232
 
226
233
  shared_examples_for "Tag (2)" do
data/spec/user_spec.rb CHANGED
@@ -125,4 +125,12 @@ describe "empty db" do
125
125
  a.siblings.should be_empty
126
126
  b1.siblings.should =~ [b2, b3]
127
127
  end
128
+
129
+ it "properly nullifies descendents" do
130
+ c = User.find_or_create_by_path %w(a b c)
131
+ b = c.parent
132
+ c.root.destroy
133
+ b.reload.should be_root
134
+ b.child_ids.should == [c.id]
135
+ end
128
136
  end
metadata CHANGED
@@ -1,215 +1,129 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: closure_tree
3
- version: !ruby/object:Gem::Version
4
- version: 3.8.2
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.9.0
6
5
  platform: ruby
7
- authors:
6
+ authors:
8
7
  - Matthew McEachen
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-03-03 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
11
+
12
+ date: 2013-03-06 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: 3.0.0
22
16
  type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
29
21
  version: 3.0.0
30
- - !ruby/object:Gem::Dependency
22
+ version_requirements: *id001
23
+ prerelease: false
24
+ - !ruby/object:Gem::Dependency
31
25
  name: with_advisory_lock
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: 0.0.6
38
26
  type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
27
+ requirement: &id002 !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
45
31
  version: 0.0.6
46
- - !ruby/object:Gem::Dependency
32
+ version_requirements: *id002
33
+ prerelease: false
34
+ - !ruby/object:Gem::Dependency
47
35
  name: rake
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
36
  type: :development
37
+ requirement: &id003 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - &id004
40
+ - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version_requirements: *id003
55
44
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- - !ruby/object:Gem::Dependency
45
+ - !ruby/object:Gem::Dependency
63
46
  name: yard
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ! '>='
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
47
  type: :development
48
+ requirement: &id005 !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - *id004
51
+ version_requirements: *id005
71
52
  prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
- - !ruby/object:Gem::Dependency
53
+ - !ruby/object:Gem::Dependency
79
54
  name: rspec
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ! '>='
84
- - !ruby/object:Gem::Version
85
- version: '0'
86
55
  type: :development
56
+ requirement: &id006 !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - *id004
59
+ version_requirements: *id006
87
60
  prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ! '>='
92
- - !ruby/object:Gem::Version
93
- version: '0'
94
- - !ruby/object:Gem::Dependency
61
+ - !ruby/object:Gem::Dependency
95
62
  name: rails
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ! '>='
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
63
  type: :development
64
+ requirement: &id007 !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - *id004
67
+ version_requirements: *id007
103
68
  prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ! '>='
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
- - !ruby/object:Gem::Dependency
69
+ - !ruby/object:Gem::Dependency
111
70
  name: rspec-rails
112
- requirement: !ruby/object:Gem::Requirement
113
- none: false
114
- requirements:
115
- - - ! '>='
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
71
  type: :development
72
+ requirement: &id008 !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - *id004
75
+ version_requirements: *id008
119
76
  prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
- requirements:
123
- - - ! '>='
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
77
+ - !ruby/object:Gem::Dependency
127
78
  name: mysql2
128
- requirement: !ruby/object:Gem::Requirement
129
- none: false
130
- requirements:
131
- - - ! '>='
132
- - !ruby/object:Gem::Version
133
- version: '0'
134
79
  type: :development
80
+ requirement: &id009 !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - *id004
83
+ version_requirements: *id009
135
84
  prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ! '>='
140
- - !ruby/object:Gem::Version
141
- version: '0'
142
- - !ruby/object:Gem::Dependency
85
+ - !ruby/object:Gem::Dependency
143
86
  name: pg
144
- requirement: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ! '>='
148
- - !ruby/object:Gem::Version
149
- version: '0'
150
87
  type: :development
88
+ requirement: &id010 !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - *id004
91
+ version_requirements: *id010
151
92
  prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
- requirements:
155
- - - ! '>='
156
- - !ruby/object:Gem::Version
157
- version: '0'
158
- - !ruby/object:Gem::Dependency
93
+ - !ruby/object:Gem::Dependency
159
94
  name: sqlite3
160
- requirement: !ruby/object:Gem::Requirement
161
- none: false
162
- requirements:
163
- - - ! '>='
164
- - !ruby/object:Gem::Version
165
- version: '0'
166
95
  type: :development
96
+ requirement: &id011 !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - *id004
99
+ version_requirements: *id011
167
100
  prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
- requirements:
171
- - - ! '>='
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- - !ruby/object:Gem::Dependency
101
+ - !ruby/object:Gem::Dependency
175
102
  name: uuidtools
176
- requirement: !ruby/object:Gem::Requirement
177
- none: false
178
- requirements:
179
- - - ! '>='
180
- - !ruby/object:Gem::Version
181
- version: '0'
182
103
  type: :development
104
+ requirement: &id012 !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - *id004
107
+ version_requirements: *id012
183
108
  prerelease: false
184
- version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
- requirements:
187
- - - ! '>='
188
- - !ruby/object:Gem::Version
189
- version: '0'
190
- - !ruby/object:Gem::Dependency
109
+ - !ruby/object:Gem::Dependency
191
110
  name: strong_parameters
192
- requirement: !ruby/object:Gem::Requirement
193
- none: false
194
- requirements:
195
- - - ! '>='
196
- - !ruby/object:Gem::Version
197
- version: '0'
198
111
  type: :development
112
+ requirement: &id013 !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - *id004
115
+ version_requirements: *id013
199
116
  prerelease: false
200
- version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
- requirements:
203
- - - ! '>='
204
- - !ruby/object:Gem::Version
205
- version: '0'
206
117
  description: Easily and efficiently make your ActiveRecord model support hierarchies
207
- email:
118
+ email:
208
119
  - matthew-github@mceachen.org
209
120
  executables: []
121
+
210
122
  extensions: []
123
+
211
124
  extra_rdoc_files: []
212
- files:
125
+
126
+ files:
213
127
  - lib/closure_tree/acts_as_tree.rb
214
128
  - lib/closure_tree/columns.rb
215
129
  - lib/closure_tree/deterministic_ordering.rb
@@ -236,35 +150,28 @@ files:
236
150
  - spec/user_spec.rb
237
151
  homepage: http://matthew.mceachen.us/closure_tree
238
152
  licenses: []
153
+
154
+ metadata: {}
155
+
239
156
  post_install_message:
240
157
  rdoc_options: []
241
- require_paths:
158
+
159
+ require_paths:
242
160
  - lib
243
- required_ruby_version: !ruby/object:Gem::Requirement
244
- none: false
245
- requirements:
246
- - - ! '>='
247
- - !ruby/object:Gem::Version
248
- version: '0'
249
- segments:
250
- - 0
251
- hash: 625197628069455012
252
- required_rubygems_version: !ruby/object:Gem::Requirement
253
- none: false
254
- requirements:
255
- - - ! '>='
256
- - !ruby/object:Gem::Version
257
- version: '0'
258
- segments:
259
- - 0
260
- hash: 625197628069455012
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - *id004
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - *id004
261
167
  requirements: []
168
+
262
169
  rubyforge_project:
263
- rubygems_version: 1.8.23
170
+ rubygems_version: 2.0.0
264
171
  signing_key:
265
- specification_version: 3
172
+ specification_version: 4
266
173
  summary: Easily and efficiently make your ActiveRecord model support hierarchies
267
- test_files:
174
+ test_files:
268
175
  - spec/cuisine_type_spec.rb
269
176
  - spec/db/database.yml
270
177
  - spec/db/schema.rb