closure_tree 6.5.0 → 6.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/Appraisals +3 -8
- data/CHANGELOG.md +60 -42
- data/README.md +27 -18
- data/gemfiles/{activerecord_5.0_foreigner.gemfile → activerecord_5.1.gemfile} +1 -2
- data/lib/closure_tree/has_closure_tree.rb +2 -0
- data/lib/closure_tree/has_closure_tree_root.rb +2 -0
- data/lib/closure_tree/hierarchy_maintenance.rb +5 -2
- data/lib/closure_tree/numeric_deterministic_ordering.rb +7 -2
- data/lib/closure_tree/numeric_order_support.rb +2 -1
- data/lib/closure_tree/version.rb +1 -1
- data/spec/db/schema.rb +23 -23
- data/spec/pool_spec.rb +27 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2a4b1786131c2b97479335f02da9e7c07a07f68
|
4
|
+
data.tar.gz: a2a1803ef7cb252a5f6f3996b3196606abf4c396
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e088751351930a9ff34d6fbcd0468e6949bff95d4ffccdaaab36cd240163029fccc752234c3ba04ceabb819a8be9a1af39b4e11beecb38003d36da7ed17dd6de
|
7
|
+
data.tar.gz: fc9d0ce048a35d852767bbed49b3b3dae1f6bd2efe92c31b37517205a5999fb69b8ae5d7c38984537121ea00702df667a4ed4e35e170c44d307eb9ddfa528136
|
data/.travis.yml
CHANGED
@@ -4,15 +4,15 @@ language: ruby
|
|
4
4
|
rvm:
|
5
5
|
- 2.4.0
|
6
6
|
- 2.3.3
|
7
|
-
- 2.2.
|
7
|
+
- 2.2.7
|
8
8
|
# these haven't been passing for a while:
|
9
9
|
# - jruby-head
|
10
10
|
# - rbx
|
11
11
|
|
12
12
|
gemfile:
|
13
|
-
- gemfiles/
|
14
|
-
- gemfiles/activerecord_5.0_foreigner.gemfile
|
13
|
+
- gemfiles/activerecord_5.1.gemfile
|
15
14
|
- gemfiles/activerecord_5.0.gemfile
|
15
|
+
- gemfiles/activerecord_4.2.gemfile
|
16
16
|
- gemfiles/activerecord_edge.gemfile
|
17
17
|
|
18
18
|
env:
|
data/Appraisals
CHANGED
@@ -1,19 +1,14 @@
|
|
1
1
|
|
2
2
|
appraise 'activerecord-4.2' do
|
3
3
|
gem 'activerecord', '~> 4.2.0'
|
4
|
-
|
5
|
-
platforms :ruby, :rbx do
|
6
|
-
gem 'mysql2', '~> 0.3.20'
|
7
|
-
end
|
8
4
|
end
|
9
5
|
|
10
|
-
appraise 'activerecord-5.0
|
6
|
+
appraise 'activerecord-5.0' do
|
11
7
|
gem 'activerecord', '~> 5.0.0'
|
12
|
-
gem 'foreigner'
|
13
8
|
end
|
14
9
|
|
15
|
-
appraise 'activerecord-5.
|
16
|
-
gem 'activerecord', '~> 5.
|
10
|
+
appraise 'activerecord-5.1' do
|
11
|
+
gem 'activerecord', '~> 5.1.0'
|
17
12
|
end
|
18
13
|
|
19
14
|
appraise 'activerecord-edge' do
|
data/CHANGELOG.md
CHANGED
@@ -1,27 +1,45 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
### 6.
|
3
|
+
### 6.6.0
|
4
|
+
|
5
|
+
Closure Tree is now tested against Rails 5.1, and just passed 50 contributors and
|
6
|
+
1000 stars on github! 🎉!
|
7
|
+
|
8
|
+
Note that Closure Tree has moved to a new "Closure Tree" github organization.
|
9
|
+
**Future gem releases will be done by other contributors.**
|
4
10
|
|
5
|
-
*
|
6
|
-
|
11
|
+
* ActiveSupport 5.1 deprecation warnings were addressed in [PR
|
12
|
+
262](https://github.com/ClosureTree/closure_tree/pull/262). Thanks, [Charles
|
13
|
+
Pence](https://github.com/cpence)!
|
14
|
+
* ActiveSupport 5.1 test failures were fixed in
|
15
|
+
[PR 280](https://github.com/ClosureTree/closure_tree/pull/280).
|
16
|
+
Thanks, [Bobby Uhlenbrock](https://github.com/uhlenbrock)!
|
17
|
+
* A database connection was leaked at startup, fixed in [PR
|
18
|
+
263](https://github.com/ClosureTree/closure_tree/pull/263). Thanks, [Andrey
|
19
|
+
Novikov](https://github.com/Envek)!
|
20
|
+
|
21
|
+
### 6.5.0
|
7
22
|
|
23
|
+
* Merged [PR 258](https://github.com/ClosureTree/closure_tree/pull/258) which
|
24
|
+
improves hierarchy maintenance with large trees. Thanks, [Nikolay
|
25
|
+
Bekirov](https://github.com/nbekirov)!
|
8
26
|
### 6.4.0
|
9
27
|
|
10
|
-
* Merged [PR 236](https://github.com/
|
28
|
+
* Merged [PR 236](https://github.com/ClosureTree/closure_tree/pull/236) which adds documentation for `has_closure_tree_root`.
|
11
29
|
* Added ruby 2.4 and dropped Rails 4.1 from the build matrix.
|
12
30
|
|
13
31
|
### 6.3.0
|
14
32
|
|
15
|
-
* `prepend_child` [handles invalid children properly now](https://github.com/
|
33
|
+
* `prepend_child` [handles invalid children properly now](https://github.com/ClosureTree/closure_tree/issues/249).
|
16
34
|
Thanks [Amit Saxena](https://github.com/amitsaxena)!
|
17
35
|
* Dropped official support for jruby and ruby 2.0 (no code was changed)
|
18
36
|
|
19
37
|
### 6.2.0
|
20
38
|
|
21
|
-
* Fix for [MySQL lock lengths](https://github.com/
|
39
|
+
* Fix for [MySQL lock lengths](https://github.com/ClosureTree/closure_tree/issues/231).
|
22
40
|
Thanks to [Liam](https://github.com/hut8)!
|
23
|
-
* [Tom Smyth](https://github.com/hooverlunch) added [eager tree loading](https://github.com/
|
24
|
-
* Merged [PR 200](https://github.com/
|
41
|
+
* [Tom Smyth](https://github.com/hooverlunch) added [eager tree loading](https://github.com/ClosureTree/closure_tree/pull/232)
|
42
|
+
* Merged [PR 200](https://github.com/ClosureTree/closure_tree/pull/200) which may or may not add support to SQLServer 2008 (but this is not a supported RDBMS).
|
25
43
|
|
26
44
|
### 6.1.0
|
27
45
|
|
@@ -45,7 +63,7 @@
|
|
45
63
|
* Dropped support for versions of Rails 3.2 and 4.0 (which are no longer supported).
|
46
64
|
* Dropped support for Ruby 1.9 and JRuby 1.9 (which are no longer supported).
|
47
65
|
* Added support for `.hash_tree` from `.parent` and `.children`.
|
48
|
-
Addresses [PR146](https://github.com/
|
66
|
+
Addresses [PR146](https://github.com/ClosureTree/closure_tree/pull/146).
|
49
67
|
Thanks for reporting this and the breaking test, [Mike](https://github.com/mkralla11)!
|
50
68
|
|
51
69
|
### 5.2.0
|
@@ -56,7 +74,7 @@
|
|
56
74
|
* [Ryan Selk](https://github.com/rselk) made several enhancements to the migration generation (thanks!).
|
57
75
|
* [ruok5](https://github.com/ruok5) updated the README to clarify a heirarchy maintenance usecase. Thanks!
|
58
76
|
* Made migrations error with a helpful message if the target didn't have the `has_closure_tree` or
|
59
|
-
`acts_as_tree` annotation. This addresses [issue 131](https://github.com/
|
77
|
+
`acts_as_tree` annotation. This addresses [issue 131](https://github.com/ClosureTree/closure_tree/issues/131).
|
60
78
|
|
61
79
|
### 5.1.1
|
62
80
|
|
@@ -67,7 +85,7 @@
|
|
67
85
|
|
68
86
|
* [Abdelkader Boudih](https://github.com/seuros) added a database generator
|
69
87
|
for the hierarchies table. Thanks!
|
70
|
-
* [Jason Weathered](https://github.com/jasoncodes) fixed [issue #117](https://github.com/
|
88
|
+
* [Jason Weathered](https://github.com/jasoncodes) fixed [issue #117](https://github.com/ClosureTree/closure_tree/pull/117)
|
71
89
|
with the preordered traversal code that assumed the primary key column was called `id`. Thanks!
|
72
90
|
|
73
91
|
### 5.0.0
|
@@ -91,13 +109,13 @@
|
|
91
109
|
|
92
110
|
### 4.6.2
|
93
111
|
|
94
|
-
* Pulled in [106](https://github.com/
|
112
|
+
* Pulled in [106](https://github.com/ClosureTree/closure_tree/pull/106) which fixed a bug introduced
|
95
113
|
in 4.6.0 which broke if the numeric ordering column wasn't named 'sort_order'. Tests have been
|
96
114
|
added. Thanks for the fix, [Fission Xuiptz](https://github.com/fissionxuiptz)!
|
97
115
|
|
98
116
|
### 4.6.1
|
99
117
|
|
100
|
-
* Address [issue 60](https://github.com/
|
118
|
+
* Address [issue 60](https://github.com/ClosureTree/closure_tree/issues/60) (use `.empty?` rather
|
101
119
|
than `.nil?`—thanks for the suggestion, [Leonel Galán](https://github.com/leonelgalan),
|
102
120
|
[Doug Mayer](https://github.com/doxavore) and [Samnang Chhun](https://github.com/samnang)!
|
103
121
|
|
@@ -124,7 +142,7 @@
|
|
124
142
|
|
125
143
|
### 4.4.0
|
126
144
|
|
127
|
-
* Added ```.self_and_descendant_ids``` and ```.self_and_ancestors_ids``` from [PR92](https://github.com/
|
145
|
+
* Added ```.self_and_descendant_ids``` and ```.self_and_ancestors_ids``` from [PR92](https://github.com/ClosureTree/closure_tree/pull/92).
|
128
146
|
Thanks, [Kir Shatrov](https://github.com/kirs)!
|
129
147
|
|
130
148
|
* Dropped support for Rails 3.0.
|
@@ -139,7 +157,7 @@
|
|
139
157
|
### 4.2.9
|
140
158
|
|
141
159
|
* Support for Heroku's cray assets:precompile hack for Rails 4.
|
142
|
-
Addresses [issue 78](https://github.com/
|
160
|
+
Addresses [issue 78](https://github.com/ClosureTree/closure_tree/issues/78).
|
143
161
|
Thanks for the assist, [Alex Bowman](https://github.com/axlekb).
|
144
162
|
|
145
163
|
### 4.2.8
|
@@ -149,7 +167,7 @@
|
|
149
167
|
### 4.2.7
|
150
168
|
|
151
169
|
* ```self_and_ancestors``` and ```ancestry_hierarchy``` are reloaded
|
152
|
-
when nodes are reparented. Addresses [issue 68](https://github.com/
|
170
|
+
when nodes are reparented. Addresses [issue 68](https://github.com/ClosureTree/closure_tree/issues/68).
|
153
171
|
Thanks for the assist, [Ivan Stana](https://github.com/istana).
|
154
172
|
|
155
173
|
### 4.2.6
|
@@ -169,12 +187,12 @@
|
|
169
187
|
### 4.2.4
|
170
188
|
|
171
189
|
* Support for ```root?```, ```child?```, and proper parent-child associations
|
172
|
-
when both the parent and the child are not persisted. Addresses [issue 64](https://github.com/
|
190
|
+
when both the parent and the child are not persisted. Addresses [issue 64](https://github.com/ClosureTree/closure_tree/issues/64).
|
173
191
|
Thanks for the help, [Gabriel Mazetto](https://github.com/brodock)!
|
174
192
|
|
175
193
|
### 4.2.3
|
176
194
|
|
177
|
-
* Fixed ```attr_accessible?``` error introduced in 4.2.2 ([issue 66](https://github.com/
|
195
|
+
* Fixed ```attr_accessible?``` error introduced in 4.2.2 ([issue 66](https://github.com/ClosureTree/closure_tree/issues/66)).
|
178
196
|
* Switched to use new WithAdvisoryLock::DatabaseAdapterSupport (in v0.0.9) to add Postgis support
|
179
197
|
|
180
198
|
### 4.2.2
|
@@ -204,11 +222,11 @@
|
|
204
222
|
|
205
223
|
* Numeric, deterministically ordered siblings will always be [0..#{self_and_siblings.count}]
|
206
224
|
(previously, the sort order might use negative values, which broke the preordering).
|
207
|
-
Resolves [issue 49](https://github.com/
|
225
|
+
Resolves [issue 49](https://github.com/ClosureTree/closure_tree/issues/49). Thanks for the help,
|
208
226
|
[Leonel Galan](https://github.com/leonelgalan), [Juan Hoyos](https://github.com/elhoyos), and
|
209
227
|
[Michael Elfassy](https://github.com/elfassy)!
|
210
228
|
|
211
|
-
* The ```order``` option can be a symbol now. Resolves [issue 46](https://github.com/
|
229
|
+
* The ```order``` option can be a symbol now. Resolves [issue 46](https://github.com/ClosureTree/closure_tree/issues/46).
|
212
230
|
|
213
231
|
### 4.0.0
|
214
232
|
|
@@ -223,22 +241,22 @@
|
|
223
241
|
### 3.10.2
|
224
242
|
|
225
243
|
* Prevent faulty SQL statement when ```#siblings``` is called on an unsaved records.
|
226
|
-
Resolves [issue 52](https://github.com/
|
244
|
+
Resolves [issue 52](https://github.com/ClosureTree/closure_tree/pull/52). Perfect pull
|
227
245
|
request by [Gary Greyling](https://github.com/garygreyling).
|
228
246
|
|
229
247
|
* The ```.roots``` class method now correctly respects the ```:order``` option.
|
230
|
-
Resolves [issue 53](https://github.com/
|
248
|
+
Resolves [issue 53](https://github.com/ClosureTree/closure_tree/issues/53).
|
231
249
|
Thanks for finding this, [Brendon Muir](https://github.com/brendon)!
|
232
250
|
|
233
251
|
### 3.10.1
|
234
252
|
|
235
253
|
* Multipart constant names like "Admin::PageHierarchy" are now supported.
|
236
|
-
Resolves [issue 47](https://github.com/
|
254
|
+
Resolves [issue 47](https://github.com/ClosureTree/closure_tree/issues/47).
|
237
255
|
Thanks for the perfect pull request, [Simon Menke](https://github.com/fd)!
|
238
256
|
|
239
257
|
* Committing transactions involving large numbers of hierarchy model classes was very slow due
|
240
258
|
to hash collisions in the hierarchy class. A better hash implementation addressed
|
241
|
-
[issue 48](https://github.com/
|
259
|
+
[issue 48](https://github.com/ClosureTree/closure_tree/issues/48).
|
242
260
|
Thanks, [Joel Turkel](https://github.com/jturkel)!
|
243
261
|
|
244
262
|
### 3.10.0
|
@@ -267,19 +285,19 @@ All three of these improvements were suggested by Andrew Bromwich. Thanks!
|
|
267
285
|
### 3.8.0
|
268
286
|
|
269
287
|
* Support for preordered descendants. This requires a numeric sort order column.
|
270
|
-
Resolves [feature request 38](https://github.com/
|
288
|
+
Resolves [feature request 38](https://github.com/ClosureTree/closure_tree/issues/38).
|
271
289
|
* Moved modules from ```acts_as_tree``` into separate files
|
272
290
|
|
273
291
|
### 3.7.3
|
274
292
|
|
275
293
|
Due to MySQL's inability to lock rows properly, I've switched to advisory_locks for
|
276
294
|
all write paths. This will prevent deadlocks, addressing
|
277
|
-
[issue 41](https://github.com/
|
295
|
+
[issue 41](https://github.com/ClosureTree/closure_tree/issues/41).
|
278
296
|
|
279
297
|
### 3.7.2
|
280
298
|
|
281
299
|
* Support for UUID primary keys. Addresses
|
282
|
-
[issue 40](https://github.com/
|
300
|
+
[issue 40](https://github.com/ClosureTree/closure_tree/issues/40). Thanks for the pull request,
|
283
301
|
[Julien](https://github.com/calexicoz)!
|
284
302
|
|
285
303
|
### 3.7.1
|
@@ -290,7 +308,7 @@ all write paths. This will prevent deadlocks, addressing
|
|
290
308
|
### 3.7.0
|
291
309
|
|
292
310
|
**Thread safety!**
|
293
|
-
* [Advisory locks](https://github.com/
|
311
|
+
* [Advisory locks](https://github.com/ClosureTree/with_advisory_lock) were
|
294
312
|
integrated with the class-level ```find_or_create_by_path``` and ```rebuild!```.
|
295
313
|
* Pessimistic locking is used by the instance-level ```find_or_create_by_path```.
|
296
314
|
|
@@ -303,7 +321,7 @@ wasting time on the ruby side.
|
|
303
321
|
### 3.6.7
|
304
322
|
|
305
323
|
* Added workaround for ActiveRecord::Observer usage pre-db-creation. Addresses
|
306
|
-
[issue 32](https://github.com/
|
324
|
+
[issue 32](https://github.com/ClosureTree/closure_tree/issues/32).
|
307
325
|
Thanks, [Don Morrison](https://github.com/elskwid)!
|
308
326
|
|
309
327
|
### 3.6.6
|
@@ -314,28 +332,28 @@ Thanks, [James Miller](https://github.com/bensie)!
|
|
314
332
|
### 3.6.5
|
315
333
|
|
316
334
|
* Use ```quote_table_name``` instead of ```quote_column_name```. Addresses
|
317
|
-
[issue 29](https://github.com/
|
335
|
+
[issue 29](https://github.com/ClosureTree/closure_tree/issues/29). Thanks,
|
318
336
|
[Marcello Barnaba](https://github.com/vjt)!
|
319
337
|
|
320
338
|
### 3.6.4
|
321
339
|
|
322
340
|
* Use ```.pluck``` when available for ```.ids_from```. Addresses
|
323
|
-
[issue 26](https://github.com/
|
341
|
+
[issue 26](https://github.com/ClosureTree/closure_tree/issues/26). Thanks,
|
324
342
|
[Chris Sturgill](https://github.com/sturgill)!
|
325
343
|
|
326
344
|
### 3.6.3
|
327
345
|
|
328
|
-
* Fixed [issue 24](https://github.com/
|
346
|
+
* Fixed [issue 24](https://github.com/ClosureTree/closure_tree/issues/24), which optimized ```#hash_tree```
|
329
347
|
for roots. Thanks, [Saverio Trioni](https://github.com/rewritten)!
|
330
348
|
|
331
349
|
### 3.6.2
|
332
350
|
|
333
|
-
* Fixed [issue 23](https://github.com/
|
351
|
+
* Fixed [issue 23](https://github.com/ClosureTree/closure_tree/issues/23), which added support for ```#siblings```
|
334
352
|
when sort_order wasn't specified. Thanks, [Gary Greyling](https://github.com/garygreyling)!
|
335
353
|
|
336
354
|
### 3.6.1
|
337
355
|
|
338
|
-
* Fixed [issue 20](https://github.com/
|
356
|
+
* Fixed [issue 20](https://github.com/ClosureTree/closure_tree/issues/20), which affected
|
339
357
|
deterministic ordering when siblings where different STI classes. Thanks, [edwinramirez](https://github.com/edwinramirez)!
|
340
358
|
|
341
359
|
### 3.6.0
|
@@ -345,16 +363,16 @@ Added support for:
|
|
345
363
|
* ActiveRecord::Base.table_name_prefix
|
346
364
|
* ActiveRecord::Base.table_name_suffix
|
347
365
|
|
348
|
-
This addresses [issue 21](https://github.com/
|
366
|
+
This addresses [issue 21](https://github.com/ClosureTree/closure_tree/issues/21). Thanks, [Judd Blair](https://github.com/juddblair)!
|
349
367
|
|
350
368
|
### 3.5.2
|
351
369
|
|
352
370
|
* Added ```find_all_by_generation```
|
353
|
-
for [feature request 17](https://github.com/
|
371
|
+
for [feature request 17](https://github.com/ClosureTree/closure_tree/issues/17).
|
354
372
|
|
355
373
|
### 3.4.2
|
356
374
|
|
357
|
-
* Fixed [issue 18](https://github.com/
|
375
|
+
* Fixed [issue 18](https://github.com/ClosureTree/closure_tree/issues/18), which affected
|
358
376
|
append_node/prepend_node ordering when the first node didn't have an explicit order_by value
|
359
377
|
|
360
378
|
### 3.4.1
|
@@ -363,7 +381,7 @@ This addresses [issue 21](https://github.com/mceachen/closure_tree/issues/21). T
|
|
363
381
|
|
364
382
|
### 3.4.0
|
365
383
|
|
366
|
-
Fixed [issue 15](https://github.com/
|
384
|
+
Fixed [issue 15](https://github.com/ClosureTree/closure_tree/issues/15):
|
367
385
|
* "parent" is now attr_accessible, which adds support for constructor-provided parents.
|
368
386
|
* updated readme accordingly
|
369
387
|
|
@@ -373,7 +391,7 @@ Fixed [issue 15](https://github.com/mceachen/closure_tree/issues/15):
|
|
373
391
|
|
374
392
|
### 3.3.1
|
375
393
|
|
376
|
-
* Added support for partially-unsaved hierarchies [issue 13](https://github.com/
|
394
|
+
* Added support for partially-unsaved hierarchies [issue 13](https://github.com/ClosureTree/closure_tree/issues/13):
|
377
395
|
```
|
378
396
|
a = Tag.new(name: "a")
|
379
397
|
b = Tag.new(name: "b")
|
@@ -388,7 +406,7 @@ a.save
|
|
388
406
|
### 3.2.1
|
389
407
|
|
390
408
|
* Added ```ancestor_ids```, ```descendant_ids```, and ```sibling_ids```
|
391
|
-
* Added example spec to solve [issue 9](https://github.com/
|
409
|
+
* Added example spec to solve [issue 9](https://github.com/ClosureTree/closure_tree/issues/9)
|
392
410
|
|
393
411
|
### 3.2.0
|
394
412
|
|
@@ -400,7 +418,7 @@ a.save
|
|
400
418
|
|
401
419
|
### 3.0.4
|
402
420
|
|
403
|
-
* Merged [pull request](https://github.com/
|
421
|
+
* Merged [pull request](https://github.com/ClosureTree/closure_tree/pull/8) to fix ```.siblings``` and ```.self_and_siblings```
|
404
422
|
(Thanks, [eljojo](https://github.com/eljojo)!)
|
405
423
|
|
406
424
|
### 3.0.3
|
@@ -415,7 +433,7 @@ a.save
|
|
415
433
|
|
416
434
|
### 3.0.1
|
417
435
|
|
418
|
-
* Support 3.2.0's fickle deprecation of InstanceMethods (Thanks, [jheiss](https://github.com/
|
436
|
+
* Support 3.2.0's fickle deprecation of InstanceMethods (Thanks, [jheiss](https://github.com/ClosureTree/closure_tree/pull/5))!
|
419
437
|
|
420
438
|
### 3.0.0
|
421
439
|
|
data/README.md
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
# Closure Tree
|
2
2
|
|
3
|
+
__Important: please [vote on the future of ClosureTree](https://github.com/ClosureTree/closure_tree/issues/277)!__
|
4
|
+
|
3
5
|
### Closure_tree lets your ActiveRecord models act as nodes in a [tree data structure](http://en.wikipedia.org/wiki/Tree_%28data_structure%29)
|
4
6
|
|
5
7
|
Common applications include modeling hierarchical data, like tags, threaded comments, page graphs in CMSes,
|
6
8
|
and tracking user referrals.
|
7
9
|
|
8
10
|
[![Join the chat at https://gitter.im/closure_tree/Lobby](https://badges.gitter.im/closure_tree/Lobby.svg)](https://gitter.im/closure_tree/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
9
|
-
[![Build Status](https://api.travis-ci.org/
|
11
|
+
[![Build Status](https://api.travis-ci.org/ClosureTree/closure_tree.svg?branch=master)](http://travis-ci.org/ClosureTree/closure_tree)
|
10
12
|
[![Gem Version](https://badge.fury.io/rb/closure_tree.svg)](https://badge.fury.io/rb/closure_tree)
|
11
|
-
[![
|
12
|
-
[![Dependency Status](https://gemnasium.com/badges/github.com/mceachen/closure_tree.svg)](https://gemnasium.com/github.com/mceachen/closure_tree)
|
13
|
+
[![Dependency Status](https://gemnasium.com/badges/github.com/ClosureTree/closure_tree.svg)](https://gemnasium.com/github.com/ClosureTree/closure_tree)
|
13
14
|
|
14
15
|
Dramatically more performant than
|
15
16
|
[ancestry](https://github.com/stefankroes/ancestry) and
|
@@ -26,9 +27,8 @@ closure_tree has some great features:
|
|
26
27
|
* __Best-in-class mutation performance__:
|
27
28
|
* 2 SQL INSERTs on node creation
|
28
29
|
* 3 SQL INSERT/UPDATEs on node reparenting
|
29
|
-
* __Support for [concurrency](#concurrency)__ (using [with_advisory_lock](https://github.com/
|
30
|
-
*
|
31
|
-
* __Support for Ruby 2.2 and 2.3__
|
30
|
+
* __Support for [concurrency](#concurrency)__ (using [with_advisory_lock](https://github.com/ClosureTree/with_advisory_lock))
|
31
|
+
* __Tested against ActiveRecord 4.2, 5.0, and 5.1, with Ruby 2.2 and 2.3__
|
32
32
|
* Support for reparenting children (and all their descendants)
|
33
33
|
* Support for [single-table inheritance (STI)](#sti) within the hierarchy
|
34
34
|
* ```find_or_create_by_path``` for [building out heterogeneous hierarchies quickly and conveniently](#find_or_create_by_path)
|
@@ -254,7 +254,7 @@ b.hash_tree(:limit_depth => 2)
|
|
254
254
|
Without this option, ```hash_tree``` will load the entire contents of that table into RAM. Your
|
255
255
|
server may not be happy trying to do this.
|
256
256
|
|
257
|
-
HT: [ancestry](https://github.com/stefankroes/ancestry#arrangement) and [elhoyos](https://github.com/
|
257
|
+
HT: [ancestry](https://github.com/stefankroes/ancestry#arrangement) and [elhoyos](https://github.com/ClosureTree/closure_tree/issues/11)
|
258
258
|
|
259
259
|
### Eager loading
|
260
260
|
|
@@ -305,13 +305,13 @@ File.open("example.dot", "w") { |f| f.write(Tag.root.to_dot_digraph) }
|
|
305
305
|
```
|
306
306
|
Then, in a shell, ```dot -Tpng example.dot > example.png```, which produces:
|
307
307
|
|
308
|
-
![Example tree](https://raw.github.com/
|
308
|
+
![Example tree](https://raw.github.com/ClosureTree/closure_tree/master/img/example.png)
|
309
309
|
|
310
310
|
If you want to customize the label value, override the ```#to_digraph_label``` instance method in your model.
|
311
311
|
|
312
312
|
Just for kicks, this is the test tree I used for proving that preordered tree traversal was correct:
|
313
313
|
|
314
|
-
![Preordered test tree](https://raw.github.com/
|
314
|
+
![Preordered test tree](https://raw.github.com/ClosureTree/closure_tree/master/img/preorder.png)
|
315
315
|
|
316
316
|
### Available options
|
317
317
|
|
@@ -484,7 +484,7 @@ Several methods, especially ```#rebuild``` and ```#find_or_create_by_path```, ca
|
|
484
484
|
|
485
485
|
Database row-level locks work correctly with PostgreSQL, but MySQL's row-level locking is broken, and
|
486
486
|
erroneously reports deadlocks where there are none. To work around this, and have a consistent implementation
|
487
|
-
for both MySQL and PostgreSQL, [with_advisory_lock](https://github.com/
|
487
|
+
for both MySQL and PostgreSQL, [with_advisory_lock](https://github.com/ClosureTree/with_advisory_lock)
|
488
488
|
is used automatically to ensure correctness.
|
489
489
|
|
490
490
|
If you are already managing concurrency elsewhere in your application, and want to disable the use
|
@@ -499,6 +499,15 @@ end
|
|
499
499
|
Note that you *will eventually have data corruption* if you disable advisory locks, write to your
|
500
500
|
database with multiple threads, and don't provide an alternative mutex.
|
501
501
|
|
502
|
+
## I18n
|
503
|
+
|
504
|
+
You can customize error messages using [I18n](http://guides.rubyonrails.org/i18n.html):
|
505
|
+
|
506
|
+
```yaml
|
507
|
+
en-US:
|
508
|
+
closure_tree:
|
509
|
+
loop_error: Your descendant cannot be your parent!
|
510
|
+
```
|
502
511
|
|
503
512
|
## FAQ
|
504
513
|
|
@@ -508,7 +517,7 @@ Yup! [Ilya Bodrov](https://github.com/bodrovis) wrote [Nested Comments with Rail
|
|
508
517
|
|
509
518
|
### Does this work well with ```#default_scope```?
|
510
519
|
|
511
|
-
**No.** Please see [issue 86](https://github.com/
|
520
|
+
**No.** Please see [issue 86](https://github.com/ClosureTree/closure_tree/issues/86) for details.
|
512
521
|
|
513
522
|
### Can I update parentage with `update_attribute`?
|
514
523
|
|
@@ -517,7 +526,7 @@ hierarchy table.
|
|
517
526
|
|
518
527
|
### Can I assign a parent to multiple children with ```#update_all```?
|
519
528
|
|
520
|
-
**No.** Please see [issue 197](https://github.com/
|
529
|
+
**No.** Please see [issue 197](https://github.com/ClosureTree/closure_tree/issues/197) for details.
|
521
530
|
|
522
531
|
### Does this gem support multiple parents?
|
523
532
|
|
@@ -576,11 +585,11 @@ bundle install
|
|
576
585
|
|
577
586
|
### Object destroy fails with MySQL v5.7+
|
578
587
|
|
579
|
-
A bug was introduced in MySQL's query optimizer. [See the workaround here](https://github.com/
|
588
|
+
A bug was introduced in MySQL's query optimizer. [See the workaround here](https://github.com/ClosureTree/closure_tree/issues/206).
|
580
589
|
|
581
590
|
### Hierarchy maintenance errors from MySQL v5.7.9-v5.7.10
|
582
591
|
|
583
|
-
Upgrade to MySQL 5.7.12 or later if you see [this issue](https://github.com/
|
592
|
+
Upgrade to MySQL 5.7.12 or later if you see [this issue](https://github.com/ClosureTree/closure_tree/issues/190):
|
584
593
|
|
585
594
|
Mysql2::Error: You can't specify target table '*_hierarchies' for update in FROM clause
|
586
595
|
|
@@ -617,10 +626,10 @@ end
|
|
617
626
|
|
618
627
|
## Testing
|
619
628
|
|
620
|
-
Closure tree is [tested under every valid combination](http://travis-ci.org/#!/
|
629
|
+
Closure tree is [tested under every valid combination](http://travis-ci.org/#!/ClosureTree/closure_tree) of
|
621
630
|
|
622
631
|
* Ruby 2.2, 2.3
|
623
|
-
* ActiveRecord 4.2 and 5.
|
632
|
+
* ActiveRecord 4.2, 5.0, and 5.1
|
624
633
|
* PostgreSQL, MySQL, and SQLite. Concurrency tests are only run with MySQL and PostgreSQL.
|
625
634
|
|
626
635
|
Assuming you're using [rbenv](https://github.com/sstephenson/rbenv), you can use ```tests.sh``` to
|
@@ -628,12 +637,12 @@ run the test matrix locally.
|
|
628
637
|
|
629
638
|
## Change log
|
630
639
|
|
631
|
-
See the [change log](https://github.com/
|
640
|
+
See the [change log](https://github.com/ClosureTree/closure_tree/blob/master/CHANGELOG.md).
|
632
641
|
|
633
642
|
## Thanks to
|
634
643
|
|
635
644
|
* The 45+ engineers around the world that have contributed their time and code to this gem
|
636
|
-
(see the [changelog](https://github.com/
|
645
|
+
(see the [changelog](https://github.com/ClosureTree/closure_tree/blob/master/CHANGELOG.md)!)
|
637
646
|
* https://github.com/collectiveidea/awesome_nested_set
|
638
647
|
* https://github.com/patshaughnessy/class_factory
|
639
648
|
* JetBrains, which provides an [open-source license](http://www.jetbrains.com/ruby/buy/buy.jsp#openSource) to
|
@@ -29,6 +29,8 @@ module ClosureTree
|
|
29
29
|
|
30
30
|
include ClosureTree::DeterministicOrdering if _ct.order_option?
|
31
31
|
include ClosureTree::NumericDeterministicOrdering if _ct.order_is_numeric?
|
32
|
+
|
33
|
+
connection_pool.release_connection
|
32
34
|
rescue StandardError => e
|
33
35
|
raise e unless ClosureTree.configuration.database_less
|
34
36
|
end
|
@@ -35,10 +35,13 @@ module ClosureTree
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def _ct_after_save
|
38
|
-
|
38
|
+
as_5_1 = ActiveSupport.version >= Gem::Version.new('5.1.0')
|
39
|
+
changes_method = as_5_1 ? :saved_changes : :changes
|
40
|
+
|
41
|
+
if public_send(changes_method)[_ct.parent_column_name] || @was_new_record
|
39
42
|
rebuild!
|
40
43
|
end
|
41
|
-
if
|
44
|
+
if public_send(changes_method)[_ct.parent_column_name] && !@was_new_record
|
42
45
|
# Resetting the ancestral collections addresses
|
43
46
|
# https://github.com/mceachen/closure_tree/issues/68
|
44
47
|
ancestor_hierarchies.reload
|
@@ -10,8 +10,13 @@ module ClosureTree
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def _ct_reorder_prior_siblings_if_parent_changed
|
13
|
-
|
14
|
-
|
13
|
+
as_5_1 = ActiveSupport.version >= Gem::Version.new('5.1.0')
|
14
|
+
change_method = as_5_1 ? :saved_change_to_attribute? : :attribute_changed?
|
15
|
+
|
16
|
+
if public_send(change_method, _ct.parent_column_name) && !@was_new_record
|
17
|
+
attribute_method = as_5_1 ? :attribute_before_last_save : :attribute_was
|
18
|
+
|
19
|
+
was_parent_id = public_send(attribute_method, _ct.parent_column_name)
|
15
20
|
_ct.reorder_with_parent_id(was_parent_id)
|
16
21
|
end
|
17
22
|
end
|
@@ -44,7 +44,8 @@ module ClosureTree
|
|
44
44
|
FROM #{quoted_table_name}
|
45
45
|
WHERE #{where_eq(parent_column_name, parent_id)} #{min_where}
|
46
46
|
) AS t
|
47
|
-
WHERE #{quoted_table_name}.#{quoted_id_column_name} = t.id
|
47
|
+
WHERE #{quoted_table_name}.#{quoted_id_column_name} = t.id and
|
48
|
+
#{quoted_table_name}.#{quoted_order_column(false)} is distinct from t.seq + #{minimum_sort_order_value.to_i - 1}
|
48
49
|
SQL
|
49
50
|
end
|
50
51
|
|
data/lib/closure_tree/version.rb
CHANGED
data/spec/db/schema.rb
CHANGED
@@ -5,7 +5,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
5
5
|
create_table "tags" do |t|
|
6
6
|
t.string "name"
|
7
7
|
t.string "title"
|
8
|
-
t.
|
8
|
+
t.references "parent"
|
9
9
|
t.integer "sort_order"
|
10
10
|
t.timestamps null: false
|
11
11
|
end
|
@@ -13,8 +13,8 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
13
13
|
add_foreign_key(:tags, :tags, :column => 'parent_id')
|
14
14
|
|
15
15
|
create_table "tag_hierarchies", :id => false do |t|
|
16
|
-
t.
|
17
|
-
t.
|
16
|
+
t.references "ancestor", :null => false
|
17
|
+
t.references "descendant", :null => false
|
18
18
|
t.integer "generations", :null => false
|
19
19
|
end
|
20
20
|
|
@@ -61,7 +61,7 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
61
61
|
|
62
62
|
create_table "users" do |t|
|
63
63
|
t.string "email"
|
64
|
-
t.
|
64
|
+
t.references "referrer"
|
65
65
|
t.integer "group_id"
|
66
66
|
t.timestamps null: false
|
67
67
|
end
|
@@ -69,8 +69,8 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
69
69
|
add_foreign_key(:users, :users, :column => 'referrer_id')
|
70
70
|
|
71
71
|
create_table "contracts" do |t|
|
72
|
-
t.
|
73
|
-
t.
|
72
|
+
t.references "user", :null => false
|
73
|
+
t.references "contract_type"
|
74
74
|
t.string "title"
|
75
75
|
end
|
76
76
|
|
@@ -79,8 +79,8 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
79
79
|
end
|
80
80
|
|
81
81
|
create_table "referral_hierarchies", :id => false do |t|
|
82
|
-
t.
|
83
|
-
t.
|
82
|
+
t.references "ancestor", :null => false
|
83
|
+
t.references "descendant", :null => false
|
84
84
|
t.integer "generations", :null => false
|
85
85
|
end
|
86
86
|
|
@@ -91,14 +91,14 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
91
91
|
t.string "name"
|
92
92
|
t.string "type"
|
93
93
|
t.integer "column_whereby_ordering_is_inferred"
|
94
|
-
t.
|
94
|
+
t.references "mother"
|
95
95
|
end
|
96
96
|
|
97
97
|
add_foreign_key(:labels, :labels, :column => 'mother_id')
|
98
98
|
|
99
99
|
create_table "label_hierarchies", :id => false do |t|
|
100
|
-
t.
|
101
|
-
t.
|
100
|
+
t.references "ancestor", :null => false
|
101
|
+
t.references "descendant", :null => false
|
102
102
|
t.integer "generations", :null => false
|
103
103
|
end
|
104
104
|
|
@@ -107,28 +107,28 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
107
107
|
|
108
108
|
create_table "cuisine_types" do |t|
|
109
109
|
t.string "name"
|
110
|
-
t.
|
110
|
+
t.references "parent"
|
111
111
|
end
|
112
112
|
|
113
113
|
create_table "cuisine_type_hierarchies", :id => false do |t|
|
114
|
-
t.
|
115
|
-
t.
|
114
|
+
t.references "ancestor", :null => false
|
115
|
+
t.references "descendant", :null => false
|
116
116
|
t.integer "generations", :null => false
|
117
117
|
end
|
118
118
|
|
119
119
|
create_table "namespace_types" do |t|
|
120
120
|
t.string "name"
|
121
|
-
t.
|
121
|
+
t.references "parent"
|
122
122
|
end
|
123
123
|
|
124
124
|
create_table "namespace_type_hierarchies", :id => false do |t|
|
125
|
-
t.
|
126
|
-
t.
|
125
|
+
t.references "ancestor", :null => false
|
126
|
+
t.references "descendant", :null => false
|
127
127
|
t.integer "generations", :null => false
|
128
128
|
end
|
129
129
|
|
130
130
|
create_table "metal" do |t|
|
131
|
-
t.
|
131
|
+
t.references "parent"
|
132
132
|
t.string "metal_type"
|
133
133
|
t.string "value"
|
134
134
|
t.string "description"
|
@@ -138,8 +138,8 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
138
138
|
add_foreign_key(:metal, :metal, :column => 'parent_id')
|
139
139
|
|
140
140
|
create_table "metal_hierarchies", :id => false do |t|
|
141
|
-
t.
|
142
|
-
t.
|
141
|
+
t.references "ancestor", :null => false
|
142
|
+
t.references "descendant", :null => false
|
143
143
|
t.integer "generations", :null => false
|
144
144
|
end
|
145
145
|
|
@@ -148,15 +148,15 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
148
148
|
|
149
149
|
create_table 'menu_items' do |t|
|
150
150
|
t.string 'name'
|
151
|
-
t.
|
151
|
+
t.references 'parent'
|
152
152
|
t.timestamps null: false
|
153
153
|
end
|
154
154
|
|
155
155
|
add_foreign_key(:menu_items, :menu_items, :column => 'parent_id')
|
156
156
|
|
157
157
|
create_table 'menu_item_hierarchies', :id => false do |t|
|
158
|
-
t.
|
159
|
-
t.
|
158
|
+
t.references 'ancestor', :null => false
|
159
|
+
t.references 'descendant', :null => false
|
160
160
|
t.integer 'generations', :null => false
|
161
161
|
end
|
162
162
|
|
data/spec/pool_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Configuration' do
|
4
|
+
it 'returns connection to the pool after has_closure_tree setup' do
|
5
|
+
class TypeDuplicate < ActiveRecord::Base
|
6
|
+
self.table_name = "namespace_type#{table_name_suffix}"
|
7
|
+
has_closure_tree
|
8
|
+
end
|
9
|
+
expect(ActiveRecord::Base.connection_pool.active_connection?).to be_falsey # +false+ in AR 4, +nil+ in AR 5
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns connection to the pool after has_closure_tree setup with order' do
|
13
|
+
class MetalDuplicate < ActiveRecord::Base
|
14
|
+
self.table_name = "#{table_name_prefix}metal#{table_name_suffix}"
|
15
|
+
has_closure_tree order: 'sort_order', name_column: 'value'
|
16
|
+
end
|
17
|
+
expect(ActiveRecord::Base.connection_pool.active_connection?).to be_falsey
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns connection to the pool after has_closure_tree_root setup' do
|
21
|
+
class GroupDuplicate < ActiveRecord::Base
|
22
|
+
self.table_name = "#{table_name_prefix}group#{table_name_suffix}"
|
23
|
+
has_closure_tree_root :root_user
|
24
|
+
end
|
25
|
+
expect(ActiveRecord::Base.connection_pool.active_connection?).to be_falsey
|
26
|
+
end
|
27
|
+
end
|
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: 6.
|
4
|
+
version: 6.6.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: 2017-
|
11
|
+
date: 2017-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -142,7 +142,7 @@ files:
|
|
142
142
|
- closure_tree.gemspec
|
143
143
|
- gemfiles/activerecord_4.2.gemfile
|
144
144
|
- gemfiles/activerecord_5.0.gemfile
|
145
|
-
- gemfiles/activerecord_5.
|
145
|
+
- gemfiles/activerecord_5.1.gemfile
|
146
146
|
- gemfiles/activerecord_edge.gemfile
|
147
147
|
- img/example.png
|
148
148
|
- img/preorder.png
|
@@ -185,6 +185,7 @@ files:
|
|
185
185
|
- spec/model_spec.rb
|
186
186
|
- spec/namespace_type_spec.rb
|
187
187
|
- spec/parallel_spec.rb
|
188
|
+
- spec/pool_spec.rb
|
188
189
|
- spec/spec_helper.rb
|
189
190
|
- spec/support/database.rb
|
190
191
|
- spec/support/database_cleaner.rb
|
@@ -218,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
218
219
|
version: '0'
|
219
220
|
requirements: []
|
220
221
|
rubyforge_project:
|
221
|
-
rubygems_version: 2.
|
222
|
+
rubygems_version: 2.6.8
|
222
223
|
signing_key:
|
223
224
|
specification_version: 4
|
224
225
|
summary: Easily and efficiently make your ActiveRecord model support hierarchies
|
@@ -238,6 +239,7 @@ test_files:
|
|
238
239
|
- spec/model_spec.rb
|
239
240
|
- spec/namespace_type_spec.rb
|
240
241
|
- spec/parallel_spec.rb
|
242
|
+
- spec/pool_spec.rb
|
241
243
|
- spec/spec_helper.rb
|
242
244
|
- spec/support/database.rb
|
243
245
|
- spec/support/database_cleaner.rb
|