closure_tree 4.4.0 → 4.5.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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YWJiMWRmNzcwODAzNGYyNTdkZDRmMDc0YjU2NjI0YjVmMTIzYWQzMQ==
5
- data.tar.gz: !binary |-
6
- ODAyOWI2MGYzOWM5N2Y0ZGU0ZTQ4OTQyNjYwYTAyYzFkNzhhYjdlYw==
2
+ SHA1:
3
+ metadata.gz: ceda99255848a84a4d3370654ecfad42dc2b7711
4
+ data.tar.gz: 71096e3755bb3dda8039eb49e3f301930ef7cc0d
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- OGZkN2RlN2Y2NTQxN2E0ZDRkM2IxMTM4MDhlYjMxYWUwOGE3ODlmZTc2ZDEx
10
- YjhlN2IyNTA4YzE1N2MwZTMxNDEyNDhlYjQwOWNiYTU1ZDVlZTE0ODg2NWY1
11
- NzUzN2ZmMjkwYTdmMjM0MmRkNmQ5YWQ2NTRkZWM5M2I0YzRmNTk=
12
- data.tar.gz: !binary |-
13
- NzdmMmIzNDMxMjc3OTA3MjMwODM2ZmE2NzhiNzgzNzAwMmU3NGY5MzEyMTNk
14
- Njk1ZjA2MjBjMTQxOTRlYmIxZDAzMzMxNmRkZTBjNTZkNTMzNjgyNzEwZTRi
15
- NTdiOTliYTU4NmM3YzdkMmVhOWI4ODJiNTMxYjc0NDI3MjI1Yzc=
6
+ metadata.gz: f40621b5ddc3cbc1c0de1959f2720b7f1e21e209ed7952878720cbcff981993037330a9c6f1e6f4f287e862b2af82e14b99109dde5a2330c6cb5e3256a0f7acb
7
+ data.tar.gz: ecd521d391c33e3afb162c25f8760c734dd58acec6c3a875d523ec7ec5dcfb50ccbbd7601f79d2fd68e2a1e592095174381508a8e45708dd91bcf1bd658cf0a7
@@ -0,0 +1,12 @@
1
+ .bundle/
2
+ .idea/
3
+ pkg/
4
+ rdoc/
5
+ doc/
6
+ *.sqlite3.db
7
+ *.log
8
+ tmp/
9
+ .DS_Store
10
+ .yardoc/
11
+ .rvmrc
12
+ *.lock
@@ -0,0 +1,32 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.2
5
+ - ruby-head
6
+ # - rbx-2
7
+
8
+ gemfile:
9
+ - gemfiles/activerecord_3.2.gemfile
10
+ - gemfiles/activerecord_4.0.gemfile
11
+ - gemfiles/activerecord_4.1.gemfile
12
+ - gemfiles/activerecord_edge.gemfile
13
+
14
+ env:
15
+ - DB=sqlite
16
+ - DB=mysql
17
+ - DB=postgresql
18
+
19
+ script: WITH_ADVISORY_LOCK_PREFIX=$TRAVIS_JOB_ID bundle exec rake --trace all_spec_flavors
20
+
21
+ matrix:
22
+ fast_finish: true
23
+ allow_failures:
24
+ - gemfile: gemfiles/activerecord_edge.gemfile
25
+ - rvm: ruby-head
26
+ exclude:
27
+ - rvm: ruby-head
28
+ gemfile: gemfiles/activerecord_3.2.gemfile
29
+ - rvm: ruby-head
30
+ gemfile: gemfiles/activerecord_4.0.gemfile
31
+ - rvm: ruby-head
32
+ gemfile: gemfiles/activerecord_4.1.gemfile
@@ -0,0 +1,3 @@
1
+ --readme README.md
2
+ --charset utf-8
3
+ 'lib/**/*.rb'
@@ -0,0 +1,17 @@
1
+ appraise "activerecord-3.2" do
2
+ gem 'activerecord', '~> 3.2'
3
+ gem 'strong_parameters'
4
+ end
5
+
6
+ appraise "activerecord-4.0" do
7
+ gem "activerecord", "~> 4.0"
8
+ end
9
+
10
+ appraise "activerecord-4.1" do
11
+ gem "activerecord", "~> 4.1"
12
+ end
13
+
14
+ appraise "activerecord-edge" do
15
+ gem "activerecord", github: "rails/rails"
16
+ gem 'arel', github: 'rails/arel'
17
+ end
@@ -0,0 +1,317 @@
1
+ # Changelog
2
+
3
+ ### 4.5.0
4
+
5
+ * Merged a bunch of great changes from [Abdelkader Boudih](https://github.com/seuros),
6
+ including a change to use [appraisal](https://github.com/thoughtbot/appraisal)
7
+ * Added Travis builds for Rails 4.1.1 and Ruby 2.1.2
8
+ * Dropped support for Rails 3.1, as it is no longer receiving security patches.
9
+ See http://rubyonrails.org/security/ for more information.
10
+
11
+ ### 4.4.0
12
+
13
+ * Added ```.self_and_descendant_ids``` and ```.self_and_ancestors_ids``` from [PR92](https://github.com/mceachen/closure_tree/pull/92).
14
+ Thanks, [Kir Shatrov](https://github.com/kirs)!
15
+
16
+ * Dropped support for Rails 3.0.
17
+
18
+ ### 4.3.0
19
+
20
+ * Use [foreigner](https://github.com/matthuhiggins/foreigner) to prove that
21
+ things are inserted and deleted without violating foreign key constraints
22
+
23
+ * Added Rails 4.1.0.rc2 as a Travis CI build target
24
+
25
+ ### 4.2.9
26
+
27
+ * Support for Heroku's cray assets:precompile hack for Rails 4.
28
+ Addresses [issue 78](https://github.com/mceachen/closure_tree/issues/78).
29
+ Thanks for the assist, [Alex Bowman](https://github.com/axlekb).
30
+
31
+ ### 4.2.8
32
+
33
+ * More massaging for Rails 4 and ```attr_accessible``` support
34
+
35
+ ### 4.2.7
36
+
37
+ * ```self_and_ancestors``` and ```ancestry_hierarchy``` are reloaded
38
+ when nodes are reparented. Addresses [issue 68](https://github.com/mceachen/closure_tree/issues/68).
39
+ Thanks for the assist, [Ivan Stana](https://github.com/istana).
40
+
41
+ ### 4.2.6
42
+
43
+ * Explicitly added MIT licensing to the gemspec.
44
+
45
+ ### 4.2.5
46
+
47
+ * Fix for potential deadlock from ```delete_hierarchy_references``` not being called within an
48
+ advisory lock. Thanks, [Armando Guereca](https://github.com/aguereca), for finding that!
49
+
50
+ * Sped up find_or_create_by_path to skip cycle detection validation.
51
+ A node whose ancestry was 200-deep took 20 seconds to create (!!), and now takes < 1 second.
52
+
53
+ * Fixed issue with MySQL that prevented nodes > 60 levels deep from being created
54
+
55
+ ### 4.2.4
56
+
57
+ * Support for ```root?```, ```child?```, and proper parent-child associations
58
+ when both the parent and the child are not persisted. Addresses [issue 64](https://github.com/mceachen/closure_tree/issues/64).
59
+ Thanks for the help, [Gabriel Mazetto](https://github.com/brodock)!
60
+
61
+ ### 4.2.3
62
+
63
+ * Fixed ```attr_accessible?``` error introduced in 4.2.2 ([issue 66](https://github.com/mceachen/closure_tree/issues/66)).
64
+ * Switched to use new WithAdvisoryLock::DatabaseAdapterSupport (in v0.0.9) to add Postgis support
65
+
66
+ ### 4.2.2
67
+
68
+ * Support attr_accessible and strong_attributes even if you're on Rails 4
69
+
70
+ ### 4.2.1
71
+
72
+ * Deleting from NumericDeterministicOrdering doesn't create sort order gaps anymore.
73
+
74
+ ### 4.2.0
75
+
76
+ * Added ```with_ancestor(*ancestors)```. Thanks for the idea, [Matt](https://github.com/mgornick)!
77
+ * Applied [Leonel Galan](https://github.com/leonelgalan)'s fix for Strong Attribute support
78
+ * ```find_or_create_by``` now uses passed-in attributes as both selection and creation criteria.
79
+ Thanks for the help, [Judd Blair](https://github.com/juddblair)!
80
+ **Please note that this changes prior behavior—test your code with this new version!**
81
+ * ```ct_advisory_lock``` was moved into the ```_ct``` support class, to reduce model method pollution
82
+ * Moved a bunch of code into more focused piles of module mixins
83
+
84
+ ### 4.1.0
85
+
86
+ * Added support for Rails 4.0.0.rc1 and Ruby 2.0.0 (while maintaining backward compatibility with Rails 3, BOOYA)
87
+ * Added ```#to_dot_digraph```, suitable for Graphviz rendering
88
+
89
+ ### 4.0.1
90
+
91
+ * Numeric, deterministically ordered siblings will always be [0..#{self_and_siblings.count}]
92
+ (previously, the sort order might use negative values, which broke the preordering).
93
+ Resolves [issue 49](https://github.com/mceachen/closure_tree/issues/49). Thanks for the help,
94
+ [Leonel Galan](https://github.com/leonelgalan), [Juan Hoyos](https://github.com/elhoyos), and
95
+ [Michael Elfassy](https://github.com/elfassy)!
96
+
97
+ * The ```order``` option can be a symbol now. Resolves [issue 46](https://github.com/mceachen/closure_tree/issues/46).
98
+
99
+ ### 4.0.0
100
+
101
+ * Moved all of closure_tree's implementation-detail methods into a ```ClosureTree::Support```
102
+ instance, which removes almost all of the namespace pollution in your models that wasn't
103
+ for normal consumption. If you were using any of these methods, they're now available through
104
+ the "_ct" class and instance member.
105
+
106
+ *This change may break consumers*, so I incremented the major version number, even though no new
107
+ functionality was released.
108
+
109
+ ### 3.10.2
110
+
111
+ * Prevent faulty SQL statement when ```#siblings``` is called on an unsaved records.
112
+ Resolves [issue 52](https://github.com/mceachen/closure_tree/pull/52). Perfect pull
113
+ request by [Gary Greyling](https://github.com/garygreyling).
114
+
115
+ * The ```.roots``` class method now correctly respects the ```:order``` option.
116
+ Resolves [issue 53](https://github.com/mceachen/closure_tree/issues/53).
117
+ Thanks for finding this, [Brendon Muir](https://github.com/brendon)!
118
+
119
+ ### 3.10.1
120
+
121
+ * Multipart constant names like "Admin::PageHierarchy" are now supported.
122
+ Resolves [issue 47](https://github.com/mceachen/closure_tree/issues/47).
123
+ Thanks for the perfect pull request, [Simon Menke](https://github.com/fd)!
124
+
125
+ * Committing transactions involving large numbers of hierarchy model classes was very slow due
126
+ to hash collisions in the hierarchy class. A better hash implementation addressed
127
+ [issue 48](https://github.com/mceachen/closure_tree/issues/48).
128
+ Thanks, [Joel Turkel](https://github.com/jturkel)!
129
+
130
+ ### 3.10.0
131
+
132
+ * Added ```#roots_and_descendants_preordered```.
133
+ Thanks for the suggestion, [Leonel Galan](https://github.com/leonelgalan)!
134
+
135
+ ### 3.9.0
136
+
137
+ * Added ```.child_ids```.
138
+ * Removed ```dependent => destroy``` on the descendant_hierarchy and ancestor_hierarchy collections
139
+ (they were a mistake).
140
+ * Clarified documentation for creation and child associations.
141
+ Because ```Tag.create!(:parent => ...)``` requires a ```.reload```, I removed it as an example.
142
+
143
+ All three of these improvements were suggested by Andrew Bromwich. Thanks!
144
+
145
+ ### 3.8.2
146
+
147
+ * find_by_path uses 1 SELECT now. BOOM.
148
+
149
+ ### 3.8.1
150
+
151
+ * Double-check locking for find_or_create_by_path
152
+
153
+ ### 3.8.0
154
+
155
+ * Support for preordered descendants. This requires a numeric sort order column.
156
+ Resolves [feature request 38](https://github.com/mceachen/closure_tree/issues/38).
157
+ * Moved modules from ```acts_as_tree``` into separate files
158
+
159
+ ### 3.7.3
160
+
161
+ Due to MySQL's inability to lock rows properly, I've switched to advisory_locks for
162
+ all write paths. This will prevent deadlocks, addressing
163
+ [issue 41](https://github.com/mceachen/closure_tree/issues/41).
164
+
165
+ ### 3.7.2
166
+
167
+ * Support for UUID primary keys. Addresses
168
+ [issue 40](https://github.com/mceachen/closure_tree/issues/40). Thanks for the pull request,
169
+ [Julien](https://github.com/calexicoz)!
170
+
171
+ ### 3.7.1
172
+
173
+ * Moved requires into ActiveSupport.on_load
174
+ * Added ```require 'with_advisory_lock'```
175
+
176
+ ### 3.7.0
177
+
178
+ **Thread safety!**
179
+ * [Advisory locks](https://github.com/mceachen/with_advisory_lock) were
180
+ integrated with the class-level ```find_or_create_by_path``` and ```rebuild!```.
181
+ * Pessimistic locking is used by the instance-level ```find_or_create_by_path```.
182
+
183
+ ### 3.6.9
184
+
185
+ * [Don Morrison](https://github.com/elskwid) massaged the [#hash_tree](#nested-hashes) query to
186
+ be more efficient, and found a bug in ```hash_tree```'s query that resulted in duplicate rows,
187
+ wasting time on the ruby side.
188
+
189
+ ### 3.6.7
190
+
191
+ * Added workaround for ActiveRecord::Observer usage pre-db-creation. Addresses
192
+ [issue 32](https://github.com/mceachen/closure_tree/issues/32).
193
+ Thanks, [Don Morrison](https://github.com/elskwid)!
194
+
195
+ ### 3.6.6
196
+
197
+ * Added support for Rails 4's [strong parameter](https://github.com/rails/strong_parameters).
198
+ Thanks, [James Miller](https://github.com/bensie)!
199
+
200
+ ### 3.6.5
201
+
202
+ * Use ```quote_table_name``` instead of ```quote_column_name```. Addresses
203
+ [issue 29](https://github.com/mceachen/closure_tree/issues/29). Thanks,
204
+ [Marcello Barnaba](https://github.com/vjt)!
205
+
206
+ ### 3.6.4
207
+
208
+ * Use ```.pluck``` when available for ```.ids_from```. Addresses
209
+ [issue 26](https://github.com/mceachen/closure_tree/issues/26). Thanks,
210
+ [Chris Sturgill](https://github.com/sturgill)!
211
+
212
+ ### 3.6.3
213
+
214
+ * Fixed [issue 24](https://github.com/mceachen/closure_tree/issues/24), which optimized ```#hash_tree```
215
+ for roots. Thanks, [Saverio Trioni](https://github.com/rewritten)!
216
+
217
+ ### 3.6.2
218
+
219
+ * Fixed [issue 23](https://github.com/mceachen/closure_tree/issues/23), which added support for ```#siblings```
220
+ when sort_order wasn't specified. Thanks, [Gary Greyling](https://github.com/garygreyling)!
221
+
222
+ ### 3.6.1
223
+
224
+ * Fixed [issue 20](https://github.com/mceachen/closure_tree/issues/20), which affected
225
+ deterministic ordering when siblings where different STI classes. Thanks, [edwinramirez](https://github.com/edwinramirez)!
226
+
227
+ ### 3.6.0
228
+
229
+ Added support for:
230
+ * ```:hierarchy_class_name``` as an option
231
+ * ActiveRecord::Base.table_name_prefix
232
+ * ActiveRecord::Base.table_name_suffix
233
+
234
+ This addresses [issue 21](https://github.com/mceachen/closure_tree/issues/21). Thanks, [Judd Blair](https://github.com/juddblair)!
235
+
236
+ ### 3.5.2
237
+
238
+ * Added ```find_all_by_generation```
239
+ for [feature request 17](https://github.com/mceachen/closure_tree/issues/17).
240
+
241
+ ### 3.4.2
242
+
243
+ * Fixed [issue 18](https://github.com/mceachen/closure_tree/issues/18), which affected
244
+ append_node/prepend_node ordering when the first node didn't have an explicit order_by value
245
+
246
+ ### 3.4.1
247
+
248
+ * Reverted .gemspec mistake that changed add_development_dependency to add_runtime_dependency
249
+
250
+ ### 3.4.0
251
+
252
+ Fixed [issue 15](https://github.com/mceachen/closure_tree/issues/15):
253
+ * "parent" is now attr_accessible, which adds support for constructor-provided parents.
254
+ * updated readme accordingly
255
+
256
+ ### 3.3.2
257
+
258
+ * Merged calebphillips' patch for a more efficient leaves query
259
+
260
+ ### 3.3.1
261
+
262
+ * Added support for partially-unsaved hierarchies [issue 13](https://github.com/mceachen/closure_tree/issues/13):
263
+ ```
264
+ a = Tag.new(name: "a")
265
+ b = Tag.new(name: "b")
266
+ a.children << b
267
+ a.save
268
+ ```
269
+
270
+ ### 3.3.0
271
+
272
+ * Added [```hash_tree```](#nested-hashes).
273
+
274
+ ### 3.2.1
275
+
276
+ * Added ```ancestor_ids```, ```descendant_ids```, and ```sibling_ids```
277
+ * Added example spec to solve [issue 9](https://github.com/mceachen/closure_tree/issues/9)
278
+
279
+ ### 3.2.0
280
+
281
+ * Added support for deterministic ordering of nodes.
282
+
283
+ ### 3.1.0
284
+
285
+ * Switched to using ```has_many :though``` rather than ```has_and_belongs_to_many```
286
+
287
+ ### 3.0.4
288
+
289
+ * Merged [pull request](https://github.com/mceachen/closure_tree/pull/8) to fix ```.siblings``` and ```.self_and_siblings```
290
+ (Thanks, [eljojo](https://github.com/eljojo)!)
291
+
292
+ ### 3.0.3
293
+
294
+ * Added support for ActiveRecord's whitelist_attributes
295
+ (Make sure you read [the Rails Security Guide](http://guides.rubyonrails.org/security.html), and
296
+ enable ```config.active_record.whitelist_attributes``` in your ```config/application.rb``` ASAP!)
297
+
298
+ ### 3.0.2
299
+
300
+ * Fix for ancestry-loop detection (performed by a validation, not through raising an exception in before_save)
301
+
302
+ ### 3.0.1
303
+
304
+ * Support 3.2.0's fickle deprecation of InstanceMethods (Thanks, [jheiss](https://github.com/mceachen/closure_tree/pull/5))!
305
+
306
+ ### 3.0.0
307
+
308
+ * Support for polymorphic trees
309
+ * ```find_by_path``` and ```find_or_create_by_path``` signatures changed to support constructor attributes
310
+ * tested against Rails 3.1.3
311
+
312
+ ### 2.0.0
313
+
314
+ * Had to increment the major version, as rebuild! will need to be called by prior consumers to support the new ```leaves``` class and instance methods.
315
+ * Tag deletion is supported now along with ```:dependent => :destroy``` and ```:dependent => :delete_all```
316
+ * Switched from default rails plugin directory structure to rspec
317
+ * Support for running specs under different database engines: ```export DB ; for DB in sqlite3 mysql postgresql ; do rake ; done```
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gem 'foreigner', :git => 'https://github.com/mceachen/foreigner.git'
3
+ gemspec
data/README.md CHANGED
@@ -25,7 +25,7 @@ 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.1, 3.2, 4.0, and 4.1__
28
+ * __Support for Rails 3.2, 4.0, and 4.1__
29
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
@@ -53,7 +53,7 @@ for a description of different tree storage algorithms.
53
53
 
54
54
  ## Installation
55
55
 
56
- Note that closure_tree only supports Rails 3.0 and later, and has test coverage for MySQL, PostgreSQL, and SQLite.
56
+ Note that closure_tree only supports Rails 3.2 and later, and has test coverage for MySQL, PostgreSQL, and SQLite.
57
57
 
58
58
  1. Add this to your Gemfile: ```gem 'closure_tree'```
59
59
 
@@ -243,7 +243,7 @@ Just for kicks, this is the test tree I used for proving that preordered tree tr
243
243
  When you include ```acts_as_tree``` in your model, you can provide a hash to override the following defaults:
244
244
 
245
245
  * ```:parent_column_name``` to override the column name of the parent foreign key in the model's table. This defaults to "parent_id".
246
- * ```:hierarchy_table_name``` to override the hierarchy class name. This defaults to the singular name of the model + "Hierarchy", like ```TagHierarchy```.
246
+ * ```:hierarchy_class_name``` to override the hierarchy class name. This defaults to the singular name of the model + "Hierarchy", like ```TagHierarchy```.
247
247
  * ```:hierarchy_table_name``` to override the hierarchy table name. This defaults to the singular name of the model + "_hierarchies", like ```tag_hierarchies```.
248
248
  * ```:dependent``` determines what happens when a node is destroyed. Defaults to ```nullify```.
249
249
  * ```:nullify``` will simply set the parent column to null. Each child node will be considered a "root" node. This is the default.
@@ -437,6 +437,10 @@ database with multiple threads, and don't provide an alternative mutex.
437
437
 
438
438
  ## FAQ
439
439
 
440
+ ### Does this work well with ```#default_scope```?
441
+
442
+ No. Please see [issue 86](https://github.com/mceachen/closure_tree/issues/86) for details.
443
+
440
444
  ### Does this gem support multiple parents?
441
445
 
442
446
  No. This gem's API is based on the assumption that each node has either 0 or 1 parent.
@@ -484,15 +488,14 @@ end
484
488
 
485
489
  Closure tree is [tested under every valid combination](http://travis-ci.org/#!/mceachen/closure_tree) of
486
490
 
487
- * Ruby 1.9.3 and Ruby 2.0.0
488
- * The latest Rails 3.1, 3.2, 4.0, and 4.1 branches, and
489
- * MySQL and PostgreSQL. SQLite works in a single-threaded environment.
491
+ * Ruby 1.9.3 , 2.0.0 and 2.1.2
492
+ * Rubinius 2.2.6
493
+ * The latest Rails 3.2, 4.0, 4.1 and master branches
494
+ * Concurrency tests for MySQL and PostgreSQL. SQLite works in a single-threaded environment.
490
495
 
491
496
  Assuming you're using [rbenv](https://github.com/sstephenson/rbenv), you can use ```tests.sh``` to
492
497
  run the test matrix locally.
493
498
 
494
- Parallelism is not tested with Rails 3.1.x due to this [known issue](https://github.com/rails/rails/issues/7538).
495
-
496
499
  ## Change log
497
500
 
498
501
  See https://github.com/mceachen/closure_tree/blob/master/CHANGELOG.md
@@ -0,0 +1,35 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+ require 'closure_tree/version'
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'closure_tree'
6
+ gem.version = ::ClosureTree::VERSION
7
+ gem.authors = ['Matthew McEachen']
8
+ gem.email = ['matthew-github@mceachen.org']
9
+ gem.homepage = 'http://mceachen.github.io/closure_tree/'
10
+
11
+ gem.summary = %q(Easily and efficiently make your ActiveRecord model support hierarchies)
12
+ gem.description = gem.summary
13
+ gem.license = 'MIT'
14
+
15
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
16
+ gem.test_files = gem.files.grep(%r{^spec/})
17
+
18
+ gem.add_runtime_dependency 'activerecord', '>= 3.2.0'
19
+ gem.add_runtime_dependency 'with_advisory_lock', '>= 0.0.9' # <- to prevent duplicate roots
20
+
21
+ gem.add_development_dependency 'rake'
22
+ gem.add_development_dependency 'yard'
23
+ gem.add_development_dependency 'rspec'
24
+ gem.add_development_dependency 'rspec-instafail'
25
+ gem.add_development_dependency 'rspec-rails' # FIXME: for rspec-rails and rspec fixture support
26
+ gem.add_development_dependency 'mysql2'
27
+ gem.add_development_dependency 'pg'
28
+ gem.add_development_dependency 'sqlite3'
29
+ gem.add_development_dependency 'uuidtools'
30
+ gem.add_development_dependency 'database_cleaner'
31
+ gem.add_development_dependency 'appraisal'
32
+
33
+ # gem.add_development_dependency 'ruby-prof' # <- don't need this normally.
34
+ # TODO: gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
35
+ end
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "foreigner", :git => "https://github.com/mceachen/foreigner.git"
6
+ gem "activerecord", "~> 3.2"
7
+ gem "strong_parameters"
8
+
9
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "foreigner", :git => "https://github.com/mceachen/foreigner.git"
6
+ gem "activerecord", "~> 4.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "foreigner", :git => "https://github.com/mceachen/foreigner.git"
6
+ gem "activerecord", "~> 4.1"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "foreigner", :git => "https://github.com/mceachen/foreigner.git"
6
+ gem "activerecord", :github => "rails/rails"
7
+ gem "arel", :github => "rails/arel"
8
+
9
+ gemspec :path => "../"
Binary file
Binary file
@@ -1,8 +1,6 @@
1
1
  require 'active_support'
2
- require 'active_record'
3
2
 
4
3
  ActiveSupport.on_load :active_record do
5
4
  require 'closure_tree/acts_as_tree'
6
-
7
5
  ActiveRecord::Base.send :extend, ClosureTree::ActsAsTree
8
6
  end
@@ -11,6 +11,18 @@ require 'closure_tree/numeric_deterministic_ordering'
11
11
  module ClosureTree
12
12
  module ActsAsTree
13
13
  def acts_as_tree(options = {})
14
+ options.assert_valid_keys(
15
+ :base_class,
16
+ :dependent,
17
+ :hierarchy_class_name,
18
+ :hierarchy_table_name,
19
+ :name,
20
+ :name_column,
21
+ :order,
22
+ :parent_column_name,
23
+ :with_advisory_lock
24
+ )
25
+
14
26
  class_attribute :_ct
15
27
  self._ct = ClosureTree::Support.new(self, options)
16
28
 
@@ -14,11 +14,11 @@ module ClosureTree
14
14
  module ClassMethods
15
15
  # Renders the given scope as a DOT digraph, suitable for rendering by Graphviz
16
16
  def to_dot_digraph(tree_scope)
17
- id_to_instance = tree_scope.inject({}) { |h, ea| h[ea.id] = ea; h }
17
+ id_to_instance = tree_scope.reduce({}) { |h, ea| h[ea.id] = ea; h }
18
18
  output = StringIO.new
19
19
  output << "digraph G {\n"
20
20
  tree_scope.each do |ea|
21
- if id_to_instance.has_key? ea._ct_parent_id
21
+ if id_to_instance.key? ea._ct_parent_id
22
22
  output << " #{ea._ct_parent_id} -> #{ea._ct_id}\n"
23
23
  end
24
24
  output << " #{ea._ct_id} [label=\"#{ea.to_digraph_label}\"]\n"
@@ -6,39 +6,40 @@ module ClosureTree
6
6
 
7
7
  included do
8
8
  belongs_to :parent,
9
- :class_name => _ct.model_class.to_s,
10
- :foreign_key => _ct.parent_column_name,
11
- :inverse_of => :children
9
+ class_name: _ct.model_class.to_s,
10
+ foreign_key: _ct.parent_column_name,
11
+ inverse_of: :children
12
12
 
13
+ # TODO, remove when activerecord 3.2 support is dropped
13
14
  attr_accessible :parent if _ct.use_attr_accessible?
14
15
 
15
16
  order_by_generations = "#{_ct.quoted_hierarchy_table_name}.generations asc"
16
17
 
17
18
  has_many :children, *_ct.has_many_with_order_option(
18
- :class_name => _ct.model_class.to_s,
19
- :foreign_key => _ct.parent_column_name,
20
- :dependent => _ct.options[:dependent],
21
- :inverse_of => :parent)
19
+ class_name: _ct.model_class.to_s,
20
+ foreign_key: _ct.parent_column_name,
21
+ dependent: _ct.options[:dependent],
22
+ inverse_of: :parent)
22
23
 
23
24
  has_many :ancestor_hierarchies, *_ct.has_many_without_order_option(
24
- :class_name => _ct.hierarchy_class_name,
25
- :foreign_key => "descendant_id",
26
- :order => order_by_generations)
25
+ class_name: _ct.hierarchy_class_name,
26
+ foreign_key: 'descendant_id',
27
+ order: order_by_generations)
27
28
 
28
29
  has_many :self_and_ancestors, *_ct.has_many_without_order_option(
29
- :through => :ancestor_hierarchies,
30
- :source => :ancestor,
31
- :order => order_by_generations)
30
+ through: :ancestor_hierarchies,
31
+ source: :ancestor,
32
+ order: order_by_generations)
32
33
 
33
34
  has_many :descendant_hierarchies, *_ct.has_many_without_order_option(
34
- :class_name => _ct.hierarchy_class_name,
35
- :foreign_key => "ancestor_id",
36
- :order => order_by_generations)
35
+ class_name: _ct.hierarchy_class_name,
36
+ foreign_key: 'ancestor_id',
37
+ order: order_by_generations)
37
38
 
38
39
  has_many :self_and_descendants, *_ct.has_many_with_order_option(
39
- :through => :descendant_hierarchies,
40
- :source => :descendant,
41
- :order => order_by_generations)
40
+ through: :descendant_hierarchies,
41
+ source: :descendant,
42
+ order: order_by_generations)
42
43
  end
43
44
 
44
45
  # Delegate to the Support instance on the class:
@@ -76,7 +77,7 @@ module ClosureTree
76
77
  ancestors.size
77
78
  end
78
79
 
79
- alias :level :depth
80
+ alias_method :level, :depth
80
81
 
81
82
  def ancestors
82
83
  without_self(self_and_ancestors)
@@ -94,7 +95,7 @@ module ClosureTree
94
95
  # to the +name_column+.
95
96
  # (so child.ancestry_path == +%w{grandparent parent child}+
96
97
  def ancestry_path(to_s_column = _ct.name_column)
97
- self_and_ancestors.reverse.collect { |n| n.send to_s_column.to_sym }
98
+ self_and_ancestors.reverse.map { |n| n.send to_s_column.to_sym }
98
99
  end
99
100
 
100
101
  def child_ids
@@ -103,11 +103,7 @@ module ClosureTree
103
103
  end
104
104
 
105
105
  def ids_from(scope)
106
- if scope.respond_to? :pluck
107
- scope.pluck(model_class.primary_key)
108
- else
109
- scope.select(model_class.primary_key).map { |ea| ea._ct_id }
110
- end
106
+ scope.pluck(model_class.primary_key)
111
107
  end
112
108
 
113
109
  def with_advisory_lock(&block)
@@ -1,3 +1,3 @@
1
1
  module ClosureTree
2
- VERSION = Gem::Version.new('4.4.0') unless defined?(::ClosureTree::VERSION)
2
+ VERSION = Gem::Version.new('4.5.0') unless defined?(::ClosureTree::VERSION)
3
3
  end
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bundle exec ruby -I lib:spec
2
+
3
+ # Simple benchmark utility to create a closure tree based on the topology of the current filesystem
4
+
5
+ #ENV['NONUKES'] = '1'
6
+ require 'spec_helper'
7
+ require 'findler'
8
+ require 'pathname'
9
+
10
+ # Returns the current path, split into an array.
11
+ # Pathname.new("/a/b/c").path_array = ["a", "b", "c"]
12
+ class Pathname
13
+ def path_array
14
+ a = []
15
+ each_filename { |ea| a << ea }
16
+ a
17
+ end
18
+ end
19
+
20
+ cnt = 0
21
+ f = Findler.new '/'
22
+ iter = f.iterator
23
+ Tag.with_advisory_lock('closure_tree') do
24
+ while (nxt = iter.next_file) && ((cnt += 1) < 1000)
25
+ t = Tag.find_or_create_by_path(nxt.path_array)
26
+ puts "created #{nxt.to_s}"
27
+ end
28
+ end
29
+
30
+ puts "Tag.all.size: #{Tag.all.size}"
31
+ puts "TagHierarchy.all.size: #{TagHierarchy.all.size}"
32
+
33
+ puts 'Tag.roots performance:'
34
+ puts Benchmark.measure { Tag.roots.size }
35
+
36
+ puts 'Tag.leaves performance:'
37
+ puts Benchmark.measure { Tag.leaves.size }
38
+
@@ -8,7 +8,7 @@ common: &common
8
8
 
9
9
  sqlite:
10
10
  adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3
11
- database: spec/sqlite3.db
11
+ database: ':memory:'
12
12
 
13
13
  postgresql:
14
14
  <<: *common
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe ClosureTree::HierarchyMaintenance do
4
+ describe '.rebuild!' do
5
+ it 'rebuild tree' do
6
+ 20.times do |counter|
7
+ Metal.create(:value => "Nitro-#{counter}", parent: Metal.all.sample)
8
+ end
9
+ hierarchy_count = MetalHierarchy.count
10
+ MetalHierarchy.delete_all
11
+ Metal.rebuild!
12
+ expect(MetalHierarchy.count).to eq(hierarchy_count)
13
+ end
14
+ end
15
+ end
@@ -49,9 +49,7 @@ describe Label do
49
49
  b = c.parent
50
50
  a = c.root
51
51
  a.destroy
52
- Label.exists?(a).should be_false
53
- Label.exists?(b).should be_false
54
- Label.exists?(c).should be_false
52
+ Label.exists?(id: [a.id,b.id,c.id]).should be_false
55
53
  end
56
54
  end
57
55
 
@@ -346,6 +344,28 @@ describe Label do
346
344
  end
347
345
  end
348
346
 
347
+ context "descendent destruction" do
348
+ it "properly destroys descendents created with add_child" do
349
+ a = Label.create(name: 'a')
350
+ b = Label.new(name: 'b')
351
+ a.add_child b
352
+ c = Label.new(name: 'c')
353
+ b.add_child c
354
+ a.destroy
355
+ Label.exists?(id: [a.id,b.id,c.id]).should be_false
356
+ end
357
+
358
+ it "properly destroys descendents created with <<" do
359
+ a = Label.create(name: 'a')
360
+ b = Label.new(name: 'b')
361
+ a.children << b
362
+ c = Label.new(name: 'c')
363
+ b.children << c
364
+ a.destroy
365
+ Label.exists?(id: [a.id,b.id,c.id]).should be_false
366
+ end
367
+ end
368
+
349
369
  context "preorder" do
350
370
  it "returns descendants in proper order" do
351
371
  create_preorder_tree
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe ClosureTree::Model do
4
+ describe '#_ct' do
5
+ it 'should delegate to the Support instance on the class' do
6
+ expect(Tag.new._ct).to eq(Tag._ct)
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'securerandom'
3
3
 
4
- describe "threadhot" do
4
+ describe "threadhot", concurrency: true do
5
5
 
6
6
  before :each do
7
7
  @iterations = 5
@@ -39,5 +39,4 @@ describe "threadhot" do
39
39
  Label.all.select { |ea| ea.root? }.should == [@target.parent]
40
40
  end
41
41
 
42
- # SQLite doesn't like parallelism, and Rails 3.0 and 3.1 have known threading issues. SKIP.
43
- end if ((ENV["DB"] != "sqlite") && (ActiveRecord::VERSION::STRING =~ /^3.2/))
42
+ end
@@ -1,11 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- parallelism_is_broken = begin
4
- # Rails < 3.2 has known bugs with parallelism
5
- (ActiveRecord::VERSION::MAJOR <= 3 && ActiveRecord::VERSION::MINOR < 2) ||
6
- # SQLite doesn't support parallel writes
7
- ENV["DB"] =~ /sqlite/
8
- end
9
3
 
10
4
  class DbThread
11
5
  def initialize(&block)
@@ -19,7 +13,7 @@ class DbThread
19
13
  end
20
14
  end
21
15
 
22
- describe "threadhot" do
16
+ describe "threadhot", concurrency: true do
23
17
 
24
18
  before :each do
25
19
  @parent = nil
@@ -144,4 +138,4 @@ describe "threadhot" do
144
138
  User.all.should be_empty
145
139
  end
146
140
 
147
- end unless parallelism_is_broken
141
+ end
@@ -1,7 +1,7 @@
1
1
  $:.unshift(File.dirname(__FILE__) + '/../lib')
2
2
  plugin_test_dir = File.dirname(__FILE__)
3
3
 
4
- require 'rubygems'
4
+
5
5
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
6
6
  require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
7
7
  require 'rspec'
@@ -17,8 +17,7 @@ if ENV['STDOUT_LOGGING']
17
17
  ActiveRecord::Base.logger = log
18
18
  end
19
19
 
20
- require 'yaml'
21
- require 'erb'
20
+
22
21
  ENV["DB"] ||= "mysql"
23
22
  ActiveRecord::Base.table_name_prefix = ENV['DB_PREFIX'].to_s
24
23
  ActiveRecord::Base.table_name_suffix = ENV['DB_SUFFIX'].to_s
@@ -32,20 +31,19 @@ ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(plugin_test_dir +
32
31
 
33
32
  def recreate_db
34
33
  db_name = ActiveRecord::Base.configurations[ENV["DB"]]["database"]
35
- case ENV['DB'] || 'mysql'
34
+ case ENV['DB']
36
35
  when 'sqlite'
37
- File.delete 'spec/sqlite3.db' if File.exist? 'spec/sqlite3.db'
38
36
  when 'postgresql'
39
37
  `psql -c 'DROP DATABASE #{db_name}' -U postgres`
40
38
  `psql -c 'CREATE DATABASE #{db_name}' -U postgres`
41
- when 'mysql'
39
+ else
42
40
  `mysql -e 'DROP DATABASE IF EXISTS #{db_name}'`
43
41
  `mysql -e 'CREATE DATABASE #{db_name}'`
44
42
  end
45
43
  ActiveRecord::Base.connection.reconnect!
46
44
  end
47
45
 
48
- ActiveRecord::Base.establish_connection(ENV["DB"])
46
+ ActiveRecord::Base.establish_connection(ENV["DB"].to_sym)
49
47
 
50
48
  ActiveRecord::Migration.verbose = false
51
49
  if ENV['NONUKES']
@@ -86,6 +84,12 @@ Thread.abort_on_exception = true
86
84
 
87
85
  DatabaseCleaner.strategy = :truncation
88
86
 
87
+
88
+ def support_concurrency
89
+ # SQLite doesn't support parallel writes
90
+ !(ENV['DB'] =~ /sqlite/)
91
+ end
92
+
89
93
  RSpec.configure do |config|
90
94
  config.before(:each) do
91
95
  DatabaseCleaner.start
@@ -100,4 +104,7 @@ RSpec.configure do |config|
100
104
  config.after(:all) do
101
105
  FileUtils.remove_entry_secure ENV['FLOCK_DIR']
102
106
  end
107
+ config.filter_run_excluding :concurrency => !support_concurrency
103
108
  end
109
+
110
+
@@ -3,4 +3,4 @@ require 'tag_examples'
3
3
 
4
4
  describe UUIDTag do
5
5
  it_behaves_like Tag
6
- end unless ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 1
6
+ end
@@ -0,0 +1,8 @@
1
+ #!/bin/sh -ex
2
+
3
+ appraisal install
4
+
5
+ for db in sqlite mysql postgresql
6
+ do
7
+ DB=$db WITH_ADVISORY_LOCK_PREFIX=$(date +%s) appraisal rake all_spec_flavors
8
+ done
metadata CHANGED
@@ -1,195 +1,195 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: closure_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0
4
+ version: 4.5.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: 2014-02-10 00:00:00.000000000 Z
11
+ date: 2014-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.0
19
+ version: 3.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.0.0
26
+ version: 3.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: with_advisory_lock
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.0.9
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.0.9
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: yard
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec-instafail
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ! '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ! '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: fuubar
98
+ name: rspec-rails
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ! '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ! '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: rspec-rails
112
+ name: mysql2
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ! '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ! '>='
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: mysql2
126
+ name: pg
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ! '>='
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ! '>='
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: pg
140
+ name: sqlite3
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - ! '>='
143
+ - - ">="
144
144
  - !ruby/object:Gem::Version
145
145
  version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - ! '>='
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: sqlite3
154
+ name: uuidtools
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - ! '>='
157
+ - - ">="
158
158
  - !ruby/object:Gem::Version
159
159
  version: '0'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - ! '>='
164
+ - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
167
  - !ruby/object:Gem::Dependency
168
- name: uuidtools
168
+ name: database_cleaner
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - ! '>='
171
+ - - ">="
172
172
  - !ruby/object:Gem::Version
173
173
  version: '0'
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - ! '>='
178
+ - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
181
  - !ruby/object:Gem::Dependency
182
- name: database_cleaner
182
+ name: appraisal
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - ! '>='
185
+ - - ">="
186
186
  - !ruby/object:Gem::Version
187
187
  version: '0'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
- - - ! '>='
192
+ - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  description: Easily and efficiently make your ActiveRecord model support hierarchies
@@ -199,9 +199,22 @@ executables: []
199
199
  extensions: []
200
200
  extra_rdoc_files: []
201
201
  files:
202
+ - ".gitignore"
203
+ - ".travis.yml"
204
+ - ".yardopts"
205
+ - Appraisals
206
+ - CHANGELOG.md
207
+ - Gemfile
202
208
  - MIT-LICENSE
203
209
  - README.md
204
210
  - Rakefile
211
+ - closure_tree.gemspec
212
+ - gemfiles/activerecord_3.2.gemfile
213
+ - gemfiles/activerecord_4.0.gemfile
214
+ - gemfiles/activerecord_4.1.gemfile
215
+ - gemfiles/activerecord_edge.gemfile
216
+ - img/example.png
217
+ - img/preorder.png
205
218
  - lib/closure_tree.rb
206
219
  - lib/closure_tree/acts_as_tree.rb
207
220
  - lib/closure_tree/deterministic_ordering.rb
@@ -216,12 +229,15 @@ files:
216
229
  - lib/closure_tree/support_attributes.rb
217
230
  - lib/closure_tree/support_flags.rb
218
231
  - lib/closure_tree/version.rb
232
+ - mktree.rb
219
233
  - spec/cuisine_type_spec.rb
220
234
  - spec/db/database.yml
221
235
  - spec/db/schema.rb
222
236
  - spec/fixtures/tags.yml
237
+ - spec/hierarchy_maintenance_spec.rb
223
238
  - spec/label_spec.rb
224
239
  - spec/metal_spec.rb
240
+ - spec/model_spec.rb
225
241
  - spec/namespace_type_spec.rb
226
242
  - spec/parallel_prepend_sibling_spec.rb
227
243
  - spec/parallel_spec.rb
@@ -232,6 +248,7 @@ files:
232
248
  - spec/tag_spec.rb
233
249
  - spec/user_spec.rb
234
250
  - spec/uuid_tag_spec.rb
251
+ - tests.sh
235
252
  homepage: http://mceachen.github.io/closure_tree/
236
253
  licenses:
237
254
  - MIT
@@ -242,17 +259,17 @@ require_paths:
242
259
  - lib
243
260
  required_ruby_version: !ruby/object:Gem::Requirement
244
261
  requirements:
245
- - - ! '>='
262
+ - - ">="
246
263
  - !ruby/object:Gem::Version
247
264
  version: '0'
248
265
  required_rubygems_version: !ruby/object:Gem::Requirement
249
266
  requirements:
250
- - - ! '>='
267
+ - - ">="
251
268
  - !ruby/object:Gem::Version
252
269
  version: '0'
253
270
  requirements: []
254
271
  rubyforge_project:
255
- rubygems_version: 2.2.0
272
+ rubygems_version: 2.2.2
256
273
  signing_key:
257
274
  specification_version: 4
258
275
  summary: Easily and efficiently make your ActiveRecord model support hierarchies
@@ -261,8 +278,10 @@ test_files:
261
278
  - spec/db/database.yml
262
279
  - spec/db/schema.rb
263
280
  - spec/fixtures/tags.yml
281
+ - spec/hierarchy_maintenance_spec.rb
264
282
  - spec/label_spec.rb
265
283
  - spec/metal_spec.rb
284
+ - spec/model_spec.rb
266
285
  - spec/namespace_type_spec.rb
267
286
  - spec/parallel_prepend_sibling_spec.rb
268
287
  - spec/parallel_spec.rb