closure_tree 4.3.0 → 4.4.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 +8 -8
- data/README.md +7 -8
- data/Rakefile +2 -2
- data/lib/closure_tree/model.rb +8 -0
- data/lib/closure_tree/support.rb +6 -3
- data/lib/closure_tree/version.rb +1 -1
- data/spec/db/database.yml +1 -1
- data/spec/parallel_spec.rb +0 -1
- data/spec/support_spec.rb +14 -0
- data/spec/user_spec.rb +10 -0
- metadata +9 -21
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YWJiMWRmNzcwODAzNGYyNTdkZDRmMDc0YjU2NjI0YjVmMTIzYWQzMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ODAyOWI2MGYzOWM5N2Y0ZGU0ZTQ4OTQyNjYwYTAyYzFkNzhhYjdlYw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OGZkN2RlN2Y2NTQxN2E0ZDRkM2IxMTM4MDhlYjMxYWUwOGE3ODlmZTc2ZDEx
|
10
|
+
YjhlN2IyNTA4YzE1N2MwZTMxNDEyNDhlYjQwOWNiYTU1ZDVlZTE0ODg2NWY1
|
11
|
+
NzUzN2ZmMjkwYTdmMjM0MmRkNmQ5YWQ2NTRkZWM5M2I0YzRmNTk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NzdmMmIzNDMxMjc3OTA3MjMwODM2ZmE2NzhiNzgzNzAwMmU3NGY5MzEyMTNk
|
14
|
+
Njk1ZjA2MjBjMTQxOTRlYmIxZDAzMzMxNmRkZTBjNTZkNTMzNjgyNzEwZTRi
|
15
|
+
NTdiOTliYTU4NmM3YzdkMmVhOWI4ODJiNTMxYjc0NDI3MjI1Yzc=
|
data/README.md
CHANGED
@@ -25,8 +25,8 @@ closure_tree has some great features:
|
|
25
25
|
* __Best-in-class mutation performance__:
|
26
26
|
* 2 SQL INSERTs on node creation
|
27
27
|
* 3 SQL INSERT/UPDATEs on node reparenting
|
28
|
-
* __Support for Rails 3.
|
29
|
-
* Support for reparenting children (and all their
|
28
|
+
* __Support for Rails 3.1, 3.2, 4.0, and 4.1__
|
29
|
+
* Support for reparenting children (and all their descendants)
|
30
30
|
* Support for [concurrency](#concurrency) (using [with_advisory_lock](https://github.com/mceachen/with_advisory_lock))
|
31
31
|
* Support for polymorphism [STI](#sti) within the hierarchy
|
32
32
|
* ```find_or_create_by_path``` for [building out hierarchies quickly and conveniently](#find_or_create_by_path)
|
@@ -279,12 +279,14 @@ When you include ```acts_as_tree``` in your model, you can provide a hash to ove
|
|
279
279
|
* ```tag.ancestors``` is a ordered scope of [ parent, grandparent, great grandparent, … ]. Note that the size of this array will always equal ```tag.depth```.
|
280
280
|
* ```tag.ancestor_ids``` is an array of the IDs of the ancestors.
|
281
281
|
* ```tag.self_and_ancestors``` returns a scope containing self, parent, grandparent, great grandparent, etc.
|
282
|
+
* ```tag.self_and_ancestors_ids``` returns IDs containing self, parent, grandparent, great grandparent, etc.
|
282
283
|
* ```tag.siblings``` returns a scope containing all nodes with the same parent as ```tag```, excluding self.
|
283
284
|
* ```tag.sibling_ids``` returns an array of the IDs of the siblings.
|
284
285
|
* ```tag.self_and_siblings``` returns a scope containing all nodes with the same parent as ```tag```, including self.
|
285
286
|
* ```tag.descendants``` returns a scope of all children, childrens' children, etc., excluding self ordered by depth.
|
286
287
|
* ```tag.descendant_ids``` returns an array of the IDs of the descendants.
|
287
|
-
* ```tag.self_and_descendants``` returns a scope of all children, childrens' children, etc.,
|
288
|
+
* ```tag.self_and_descendants``` returns a scope of self, all children, childrens' children, etc., ordered by depth.
|
289
|
+
* ```tag.self_and_descendant_ids``` returns IDs of self, all children, childrens' children, etc., ordered by depth.
|
288
290
|
* ```tag.hash_tree``` returns an [ordered, nested hash](#nested-hashes) that can be depth-limited.
|
289
291
|
* ```tag.find_by_path(path)``` returns the node whose name path *from ```tag```* is ```path```. See (#find_or_create_by_path).
|
290
292
|
* ```tag.find_or_create_by_path(path)``` returns the node whose name path *from ```tag```* is ```path```, and will create the node if it doesn't exist already.See (#find_or_create_by_path).
|
@@ -478,21 +480,18 @@ after do
|
|
478
480
|
end
|
479
481
|
```
|
480
482
|
|
481
|
-
|
482
483
|
## Testing
|
483
484
|
|
484
485
|
Closure tree is [tested under every valid combination](http://travis-ci.org/#!/mceachen/closure_tree) of
|
485
486
|
|
486
487
|
* Ruby 1.9.3 and Ruby 2.0.0
|
487
|
-
* The latest Rails 3.
|
488
|
+
* The latest Rails 3.1, 3.2, 4.0, and 4.1 branches, and
|
488
489
|
* MySQL and PostgreSQL. SQLite works in a single-threaded environment.
|
489
490
|
|
490
491
|
Assuming you're using [rbenv](https://github.com/sstephenson/rbenv), you can use ```tests.sh``` to
|
491
492
|
run the test matrix locally.
|
492
493
|
|
493
|
-
Parallelism is not tested with Rails 3.
|
494
|
-
[known issue](https://github.com/rails/rails/issues/7538).
|
495
|
-
|
494
|
+
Parallelism is not tested with Rails 3.1.x due to this [known issue](https://github.com/rails/rails/issues/7538).
|
496
495
|
|
497
496
|
## Change log
|
498
497
|
|
data/Rakefile
CHANGED
@@ -18,11 +18,11 @@ task :default => :spec
|
|
18
18
|
|
19
19
|
task :all_spec_flavors do
|
20
20
|
[["", ""], ["db_prefix_", ""], ["", "_db_suffix"], ["abc_", "_123"]].each do |prefix, suffix|
|
21
|
-
fail unless system("rake spec DB_PREFIX=#{prefix} DB_SUFFIX=#{suffix}")
|
21
|
+
fail unless system("bundle exec rake spec DB_PREFIX=#{prefix} DB_SUFFIX=#{suffix}")
|
22
22
|
end
|
23
23
|
require 'active_record/version'
|
24
24
|
if ActiveRecord::VERSION::MAJOR == 3
|
25
|
-
system("rake spec ATTR_ACCESSIBLE=1")
|
25
|
+
fail unless system("rake spec ATTR_ACCESSIBLE=1")
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
data/lib/closure_tree/model.rb
CHANGED
@@ -86,6 +86,10 @@ module ClosureTree
|
|
86
86
|
_ct.ids_from(ancestors)
|
87
87
|
end
|
88
88
|
|
89
|
+
def self_and_ancestors_ids
|
90
|
+
_ct.ids_from(self_and_ancestors)
|
91
|
+
end
|
92
|
+
|
89
93
|
# Returns an array, root first, of self_and_ancestors' values of the +to_s_column+, which defaults
|
90
94
|
# to the +name_column+.
|
91
95
|
# (so child.ancestry_path == +%w{grandparent parent child}+
|
@@ -101,6 +105,10 @@ module ClosureTree
|
|
101
105
|
without_self(self_and_descendants)
|
102
106
|
end
|
103
107
|
|
108
|
+
def self_and_descendant_ids
|
109
|
+
_ct.ids_from(self_and_descendants)
|
110
|
+
end
|
111
|
+
|
104
112
|
def descendant_ids
|
105
113
|
_ct.ids_from(descendants)
|
106
114
|
end
|
data/lib/closure_tree/support.rb
CHANGED
@@ -94,9 +94,12 @@ module ClosureTree
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def remove_prefix_and_suffix(table_name)
|
97
|
-
|
98
|
-
|
99
|
-
|
97
|
+
pre, suff = ActiveRecord::Base.table_name_prefix, ActiveRecord::Base.table_name_suffix
|
98
|
+
if table_name.start_with?(pre) && table_name.end_with?(suff)
|
99
|
+
table_name[pre.size..-(suff.size + 1)]
|
100
|
+
else
|
101
|
+
table_name
|
102
|
+
end
|
100
103
|
end
|
101
104
|
|
102
105
|
def ids_from(scope)
|
data/lib/closure_tree/version.rb
CHANGED
data/spec/db/database.yml
CHANGED
data/spec/parallel_spec.rb
CHANGED
@@ -42,7 +42,6 @@ describe "threadhot" do
|
|
42
42
|
end
|
43
43
|
max_wait_time = @lock.synchronize { @wake_times.max }
|
44
44
|
sleep_time = max_wait_time - Time.now.to_f
|
45
|
-
$stderr.puts "sleeping for #{sleep_time}"
|
46
45
|
sleep(sleep_time)
|
47
46
|
(@parent || Tag).find_or_create_by_path([name.to_s, :a, :b, :c])
|
48
47
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ClosureTree::Support do
|
4
|
+
let(:sut) { Tag._ct }
|
5
|
+
it 'passes through table names without prefix and suffix' do
|
6
|
+
expected = 'some_random_table_name'
|
7
|
+
sut.remove_prefix_and_suffix(expected).should == expected
|
8
|
+
end
|
9
|
+
it 'extracts through table name with prefix and suffix' do
|
10
|
+
expected = 'some_random_table_name'
|
11
|
+
tn = ActiveRecord::Base.table_name_prefix + expected + ActiveRecord::Base.table_name_suffix
|
12
|
+
sut.remove_prefix_and_suffix(tn).should == expected
|
13
|
+
end
|
14
|
+
end
|
data/spec/user_spec.rb
CHANGED
@@ -38,6 +38,14 @@ describe "empty db" do
|
|
38
38
|
User.all.to_a.should =~ [@root, @mid, @leaf]
|
39
39
|
end
|
40
40
|
|
41
|
+
it 'orders self_and_ancestor_ids nearest generation first' do
|
42
|
+
@leaf.self_and_ancestor_ids.should == [@leaf.id, @mid.id, @root.id]
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'orders self_and_descendant_ids nearest generation first' do
|
46
|
+
@root.self_and_descendant_ids.should == [@root.id, @mid.id, @leaf.id]
|
47
|
+
end
|
48
|
+
|
41
49
|
it "should have children" do
|
42
50
|
@root.children.to_a.should == [@mid]
|
43
51
|
@mid.children.to_a.should == [@leaf]
|
@@ -84,8 +92,10 @@ describe "empty db" do
|
|
84
92
|
u = User.find_or_create_by_path(%w(a@t.co b@t.co c@t.co))
|
85
93
|
u.descendant_ids.should == []
|
86
94
|
u.ancestor_ids.should == [u.parent.id, u.root.id]
|
95
|
+
u.self_and_ancestor_ids.should == [u.id, u.parent.id, u.root.id]
|
87
96
|
u.root.descendant_ids.should == [u.parent.id, u.id]
|
88
97
|
u.root.ancestor_ids.should == []
|
98
|
+
u.root.self_and_ancestor_ids.should == [u.root.id]
|
89
99
|
c1 = u.contracts.create!
|
90
100
|
c2 = u.parent.contracts.create!
|
91
101
|
u.root.indirect_contracts.to_a.should =~ [c1, c2]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: closure_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew McEachen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -178,20 +178,6 @@ dependencies:
|
|
178
178
|
- - ! '>='
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
|
-
- !ruby/object:Gem::Dependency
|
182
|
-
name: foreigner
|
183
|
-
requirement: !ruby/object:Gem::Requirement
|
184
|
-
requirements:
|
185
|
-
- - ! '>='
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: '0'
|
188
|
-
type: :development
|
189
|
-
prerelease: false
|
190
|
-
version_requirements: !ruby/object:Gem::Requirement
|
191
|
-
requirements:
|
192
|
-
- - ! '>='
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: '0'
|
195
181
|
- !ruby/object:Gem::Dependency
|
196
182
|
name: database_cleaner
|
197
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -213,6 +199,10 @@ executables: []
|
|
213
199
|
extensions: []
|
214
200
|
extra_rdoc_files: []
|
215
201
|
files:
|
202
|
+
- MIT-LICENSE
|
203
|
+
- README.md
|
204
|
+
- Rakefile
|
205
|
+
- lib/closure_tree.rb
|
216
206
|
- lib/closure_tree/acts_as_tree.rb
|
217
207
|
- lib/closure_tree/deterministic_ordering.rb
|
218
208
|
- lib/closure_tree/digraphs.rb
|
@@ -226,10 +216,6 @@ files:
|
|
226
216
|
- lib/closure_tree/support_attributes.rb
|
227
217
|
- lib/closure_tree/support_flags.rb
|
228
218
|
- lib/closure_tree/version.rb
|
229
|
-
- lib/closure_tree.rb
|
230
|
-
- MIT-LICENSE
|
231
|
-
- Rakefile
|
232
|
-
- README.md
|
233
219
|
- spec/cuisine_type_spec.rb
|
234
220
|
- spec/db/database.yml
|
235
221
|
- spec/db/schema.rb
|
@@ -241,6 +227,7 @@ files:
|
|
241
227
|
- spec/parallel_spec.rb
|
242
228
|
- spec/spec_helper.rb
|
243
229
|
- spec/support/models.rb
|
230
|
+
- spec/support_spec.rb
|
244
231
|
- spec/tag_examples.rb
|
245
232
|
- spec/tag_spec.rb
|
246
233
|
- spec/user_spec.rb
|
@@ -265,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
265
252
|
version: '0'
|
266
253
|
requirements: []
|
267
254
|
rubyforge_project:
|
268
|
-
rubygems_version: 2.
|
255
|
+
rubygems_version: 2.2.0
|
269
256
|
signing_key:
|
270
257
|
specification_version: 4
|
271
258
|
summary: Easily and efficiently make your ActiveRecord model support hierarchies
|
@@ -281,6 +268,7 @@ test_files:
|
|
281
268
|
- spec/parallel_spec.rb
|
282
269
|
- spec/spec_helper.rb
|
283
270
|
- spec/support/models.rb
|
271
|
+
- spec/support_spec.rb
|
284
272
|
- spec/tag_examples.rb
|
285
273
|
- spec/tag_spec.rb
|
286
274
|
- spec/user_spec.rb
|