lalala 4.0.0.dev.136 → 4.0.0.dev.141

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -3
  3. data/lalala.gemspec +2 -6
  4. data/lib/lalala/version.rb +1 -1
  5. data/lib/lalala.rb +0 -1
  6. metadata +19 -53
  7. data/vendor/deps/closure_tree/.gitignore +0 -12
  8. data/vendor/deps/closure_tree/.travis.yml +0 -22
  9. data/vendor/deps/closure_tree/.yardopts +0 -3
  10. data/vendor/deps/closure_tree/Gemfile +0 -2
  11. data/vendor/deps/closure_tree/MIT-LICENSE +0 -19
  12. data/vendor/deps/closure_tree/README.md +0 -641
  13. data/vendor/deps/closure_tree/Rakefile +0 -26
  14. data/vendor/deps/closure_tree/ci/Gemfile.rails-3.0.x +0 -5
  15. data/vendor/deps/closure_tree/ci/Gemfile.rails-3.1.x +0 -4
  16. data/vendor/deps/closure_tree/ci/Gemfile.rails-3.2.x +0 -4
  17. data/vendor/deps/closure_tree/closure_tree.gemspec +0 -31
  18. data/vendor/deps/closure_tree/lib/closure_tree/acts_as_tree.rb +0 -55
  19. data/vendor/deps/closure_tree/lib/closure_tree/columns.rb +0 -123
  20. data/vendor/deps/closure_tree/lib/closure_tree/deterministic_ordering.rb +0 -49
  21. data/vendor/deps/closure_tree/lib/closure_tree/model.rb +0 -386
  22. data/vendor/deps/closure_tree/lib/closure_tree/numeric_deterministic_ordering.rb +0 -93
  23. data/vendor/deps/closure_tree/lib/closure_tree/version.rb +0 -3
  24. data/vendor/deps/closure_tree/lib/closure_tree/with_advisory_lock.rb +0 -18
  25. data/vendor/deps/closure_tree/lib/closure_tree.rb +0 -8
  26. data/vendor/deps/closure_tree/spec/cuisine_type_spec.rb +0 -30
  27. data/vendor/deps/closure_tree/spec/db/database.yml +0 -19
  28. data/vendor/deps/closure_tree/spec/db/schema.rb +0 -109
  29. data/vendor/deps/closure_tree/spec/fixtures/labels.yml +0 -55
  30. data/vendor/deps/closure_tree/spec/fixtures/tags.yml +0 -98
  31. data/vendor/deps/closure_tree/spec/hash_tree_spec.rb +0 -91
  32. data/vendor/deps/closure_tree/spec/label_spec.rb +0 -356
  33. data/vendor/deps/closure_tree/spec/namespace_type_spec.rb +0 -13
  34. data/vendor/deps/closure_tree/spec/parallel_prepend_sibling_spec.rb +0 -45
  35. data/vendor/deps/closure_tree/spec/parallel_spec.rb +0 -59
  36. data/vendor/deps/closure_tree/spec/spec_helper.rb +0 -57
  37. data/vendor/deps/closure_tree/spec/support/models.rb +0 -74
  38. data/vendor/deps/closure_tree/spec/tag_spec.rb +0 -469
  39. data/vendor/deps/closure_tree/spec/user_spec.rb +0 -136
  40. data/vendor/deps/closure_tree/tests.sh +0 -19
@@ -1,641 +0,0 @@
1
- # Closure Tree [![Build Status](https://secure.travis-ci.org/mceachen/closure_tree.png?branch=master)](http://travis-ci.org/mceachen/closure_tree)
2
-
3
- ### Closure_tree lets your ActiveRecord models act as nodes in a [tree data structure](http://en.wikipedia.org/wiki/Tree_%28data_structure%29)
4
-
5
- Common applications include modeling hierarchical data, like tags, page graphs in CMSes,
6
- and tracking user referrals.
7
-
8
- Mostly API-compatible with other popular nesting gems for Rails, like
9
- [ancestry](https://github.com/stefankroes/ancestry),
10
- [acts_as_tree](https://github.com/amerine/acts_as_tree) and
11
- [awesome_nested_set](https://github.com/collectiveidea/awesome_nested_set/),
12
- closure_tree has some great features:
13
-
14
- * __Best-in-class select performance__:
15
- * Fetch your whole ancestor lineage in 1 SELECT.
16
- * Grab all your descendants in 1 SELECT.
17
- * Get all your siblings 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
- * __Best-in-class mutation performance__:
21
- * 2 SQL INSERTs on node creation
22
- * 3 SQL INSERT/UPDATEs on node reparenting
23
- * Support for reparenting children (and all their progeny)
24
- * Support for [concurrency](#concurrency) (using [with_advisory_lock](https://github/mceachen/with_advisory_lock))
25
- * Support for polymorphism [STI](#sti) within the hierarchy
26
- * ```find_or_create_by_path``` for [building out hierarchies quickly and conveniently](#find_or_create_by_path)
27
- * Support for [deterministic ordering](#deterministic-ordering) of children
28
- * Support for [preordered](http://en.wikipedia.org/wiki/Tree_traversal#Pre-order) traversal of descendants
29
- * Excellent [test coverage](#testing) in a variety of environments
30
-
31
- See [Bill Karwin](http://karwin.blogspot.com/)'s excellent
32
- [Models for hierarchical data presentation](http://www.slideshare.net/billkarwin/models-for-hierarchical-data)
33
- for a description of different tree storage algorithms.
34
-
35
- ## Table of Contents
36
-
37
- - [Installation](#installation)
38
- - [Usage](#usage)
39
- - [Accessing Data](#accessing-data)
40
- - [Polymorphic hierarchies with STI](#polymorphic-hierarchies-with-sti)
41
- - [Deterministic ordering](#deterministic-ordering)
42
- - [Concurrency](#concurrency)
43
- - [FAQ](#faq)
44
- - [Testing](#testing)
45
- - [Change log](#change-log)
46
-
47
- ## Installation
48
-
49
- Note that closure_tree only supports Rails 3.0 and later, and has test coverage for MySQL, PostgreSQL, and SQLite.
50
-
51
- 1. Add this to your Gemfile: ```gem 'closure_tree'```
52
-
53
- 2. Run ```bundle install```
54
-
55
- 3. Add ```acts_as_tree``` to your hierarchical model(s). There are a number of [options](#available-options) you can pass in, too.
56
-
57
- 4. Add a migration to add a ```parent_id``` column to the model you want to act_as_tree.
58
- You may want to also [add a column for deterministic ordering of children](#sort_order), but that's optional.
59
-
60
- ```ruby
61
- class AddParentIdToTag < ActiveRecord::Migration
62
- def change
63
- add_column :tag, :parent_id, :integer
64
- end
65
- end
66
- ```
67
-
68
- Note that if the column is null, the tag will be considered a root node.
69
-
70
- 5. Add a database migration to store the hierarchy for your model. By
71
- default the table name will be the model's table name, followed by
72
- "_hierarchies". Note that by calling ```acts_as_tree```, a "virtual model" (in this case, ```TagHierarchy```)
73
- will be added automatically, so you don't need to create it.
74
-
75
- ```ruby
76
- class CreateTagHierarchies < ActiveRecord::Migration
77
- def change
78
- create_table :tag_hierarchies, :id => false do |t|
79
- t.integer :ancestor_id, :null => false # ID of the parent/grandparent/great-grandparent/... tag
80
- t.integer :descendant_id, :null => false # ID of the target tag
81
- t.integer :generations, :null => false # Number of generations between the ancestor and the descendant. Parent/child = 1, for example.
82
- end
83
-
84
- # For "all progeny of…" selects:
85
- add_index :tag_hierarchies, [:ancestor_id, :descendant_id], :unique => true
86
-
87
- # For "all ancestors of…" selects
88
- add_index :tag_hierarchies, [:descendant_id]
89
- end
90
- end
91
- ```
92
-
93
- 6. Run ```rake db:migrate```
94
-
95
- 7. If you're migrating from another system where your model already has a
96
- ```parent_id``` column, run ```Tag.rebuild!``` and the
97
- …_hierarchy table will be truncated and rebuilt.
98
-
99
- If you're starting from scratch you don't need to call ```rebuild!```.
100
-
101
- ## Usage
102
-
103
- ### Creation
104
-
105
- Create a root node:
106
-
107
- ```ruby
108
- grandparent = Tag.create(:name => 'Grandparent')
109
- ```
110
-
111
- Child nodes are created by appending to the children collection:
112
-
113
- ```ruby
114
- parent = grandparent.children.create(:name => 'Parent')
115
- ```
116
-
117
- Or by appending to the children collection:
118
-
119
- ```ruby
120
- child2 = Tag.new(:name => 'Second Child')
121
- parent.children << child2
122
- ```
123
-
124
- Or by calling the "add_child" method:
125
-
126
- ```ruby
127
- child3 = Tag.new(:name => 'Third Child')
128
- parent.add_child child3
129
- ```
130
-
131
- Then:
132
-
133
- ```ruby
134
- grandparent.self_and_descendants.collect(&:name)
135
- => ["Grandparent", "Parent", "First Child", "Second Child", "Third Child"]
136
-
137
- child1.ancestry_path
138
- => ["Grandparent", "Parent", "First Child"]
139
- ```
140
-
141
- ### find_or_create_by_path
142
-
143
- We can do all the node creation and add_child calls with one method call:
144
-
145
- ```ruby
146
- child = Tag.find_or_create_by_path(["grandparent", "parent", "child"])
147
- ```
148
-
149
- You can ```find``` as well as ```find_or_create``` by "ancestry paths".
150
- Ancestry paths may be built using any column in your model. The default
151
- column is ```name```, which can be changed with the :name_column option
152
- provided to ```acts_as_tree```.
153
-
154
- Note that any other AR fields can be set with the second, optional ```attributes``` argument.
155
-
156
- ```ruby
157
- child = Tag.find_or_create_by_path(%w{home chuck Photos"}, {:tag_type => "File"})
158
- ```
159
- This will pass the attribute hash of ```{:name => "home", :tag_type => "File"}``` to
160
- ```Tag.find_or_create_by_name``` if the root directory doesn't exist (and
161
- ```{:name => "chuck", :tag_type => "File"}``` if the second-level tag doesn't exist, and so on).
162
-
163
- ### Moving nodes around the tree
164
-
165
- Nodes can be moved around to other parents, and closure_tree moves the node's descendancy to the new parent for you:
166
-
167
- ```ruby
168
- d = Tag.find_or_create_by_path %w(a b c d)
169
- h = Tag.find_or_create_by_path %w(e f g h)
170
- e = h.root
171
- d.add_child(e) # "d.children << e" would work too, of course
172
- h.ancestry_path
173
- => ["a", "b", "c", "d", "e", "f", "g", "h"]
174
- ```
175
-
176
- ### Nested hashes
177
-
178
- ```hash_tree``` provides a method for rendering a subtree as an
179
- ordered nested hash:
180
-
181
- ```ruby
182
- b = Tag.find_or_create_by_path %w(a b)
183
- a = b.parent
184
- b2 = Tag.find_or_create_by_path %w(a b2)
185
- d1 = b.find_or_create_by_path %w(c1 d1)
186
- c1 = d1.parent
187
- d2 = b.find_or_create_by_path %w(c2 d2)
188
- c2 = d2.parent
189
-
190
- Tag.hash_tree
191
- => {a => {b => {c1 => {d1 => {}}, c2 => {d2 => {}}}, b2 => {}}}
192
-
193
- Tag.hash_tree(:limit_depth => 2)
194
- => {a => {b => {}, b2 => {}}}
195
-
196
- b.hash_tree
197
- => {b => {c1 => {d1 => {}}, c2 => {d2 => {}}}}
198
-
199
- b.hash_tree(:limit_depth => 2)
200
- => {b => {c1 => {}, c2 => {}}}
201
- ```
202
-
203
- **If your tree is large (or might become so), use :limit_depth.**
204
-
205
- Without this option, ```hash_tree``` will load the entire contents of that table into RAM. Your
206
- server may not be happy trying to do this.
207
-
208
- HT: [ancestry](https://github.com/stefankroes/ancestry#arrangement) and [elhoyos](https://github.com/mceachen/closure_tree/issues/11)
209
-
210
- ### <a id="options"></a>Available options
211
-
212
- When you include ```acts_as_tree``` in your model, you can provide a hash to override the following defaults:
213
-
214
- * ```:parent_column_name``` to override the column name of the parent foreign key in the model's table. This defaults to "parent_id".
215
- * ```:hierarchy_table_name``` to override the hierarchy class name. This defaults to the singular name of the model + "Hierarchy", like ```TagHierarchy```.
216
- * ```:hierarchy_table_name``` to override the hierarchy table name. This defaults to the singular name of the model + "_hierarchies", like ```tag_hierarchies```.
217
- * ```:dependent``` determines what happens when a node is destroyed. Defaults to ```nullify```.
218
- * ```:nullify``` will simply set the parent column to null. Each child node will be considered a "root" node. This is the default.
219
- * ```:delete_all``` will delete all descendant nodes (which circumvents the destroy hooks)
220
- * ```:destroy``` will destroy all descendant nodes (which runs the destroy hooks on each child node)
221
- * ```:name_column``` used by #```find_or_create_by_path```, #```find_by_path```, and ```ancestry_path``` instance methods. This is primarily useful if the model only has one required field (like a "tag").
222
- * ```:order``` used to set up [deterministic ordering](#deterministic-ordering)
223
-
224
- ## Accessing Data
225
-
226
- ### Class methods
227
-
228
- * ```Tag.root``` returns an arbitrary root node
229
- * ```Tag.roots``` returns all root nodes
230
- * ```Tag.leaves``` returns all leaf nodes
231
- * ```Tag.hash_tree``` returns an [ordered, nested hash](#nested-hashes) that can be depth-limited.
232
- * ```Tag.find_by_path(path)``` returns the node whose name path is ```path```. See (#find_or_create_by_path).
233
- * ```Tag.find_or_create_by_path(path)``` returns the node whose name path is ```path```, and will create the node if it doesn't exist already.See (#find_or_create_by_path).
234
- * ```Tag.find_all_by_generation(generation_level)``` returns the descendant nodes who are ```generation_level``` away from a root. ```Tag.find_all_by_generation(0)``` is equivalent to ```Tag.roots```.
235
-
236
- ### Instance methods
237
-
238
- * ```tag.root``` returns the root for this node
239
- * ```tag.root?``` returns true if this is a root node
240
- * ```tag.child?``` returns true if this is a child node. It has a parent.
241
- * ```tag.leaf?``` returns true if this is a leaf node. It has no children.
242
- * ```tag.leaves``` is scoped to all leaf nodes in self_and_descendants.
243
- * ```tag.depth``` returns the depth, or "generation", for this node in the tree. A root node will have a value of 0.
244
- * ```tag.parent``` returns the node's immediate parent. Root nodes will return nil.
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.
247
- * ```tag.ancestors``` is a ordered scope of [ parent, grandparent, great grandparent, … ]. Note that the size of this array will always equal ```tag.depth```.
248
- * ```tag.ancestor_ids``` is an array of the IDs of the ancestors.
249
- * ```tag.self_and_ancestors``` returns a scope containing self, parent, grandparent, great grandparent, etc.
250
- * ```tag.siblings``` returns a scope containing all nodes with the same parent as ```tag```, excluding self.
251
- * ```tag.sibling_ids``` returns an array of the IDs of the siblings.
252
- * ```tag.self_and_siblings``` returns a scope containing all nodes with the same parent as ```tag```, including self.
253
- * ```tag.descendants``` returns a scope of all children, childrens' children, etc., excluding self ordered by depth.
254
- * ```tag.descendant_ids``` returns an array of the IDs of the descendants.
255
- * ```tag.self_and_descendants``` returns a scope of all children, childrens' children, etc., including self, ordered by depth.
256
- * ```tag.hash_tree``` returns an [ordered, nested hash](#nested-hashes) that can be depth-limited.
257
- * ```tag.find_by_path(path)``` returns the node whose name path *from ```tag```* is ```path```. See (#find_or_create_by_path).
258
- * ```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).
259
- * ```tag.find_all_by_generation(generation_level)``` returns the descendant nodes who are ```generation_level``` away from ```tag```.
260
- * ```tag.find_all_by_generation(0).to_a``` == ```[tag]```
261
- * ```tag.find_all_by_generation(1)``` == ```tag.children```
262
- * ```tag.find_all_by_generation(2)``` will return the tag's grandchildren, and so on.
263
- * ```tag.destroy``` will destroy a node and do <em>something</em> to its children, which is determined by the ```:dependent``` option passed to ```acts_as_tree```.
264
-
265
- ## Polymorphic hierarchies with STI
266
-
267
- Polymorphic models using single table inheritance (STI) are supported:
268
-
269
- 1. Create a db migration that adds a String ```type``` column to your model
270
- 2. Subclass the model class. You only need to add ```acts_as_tree``` to your base class:
271
-
272
- ```ruby
273
- class Tag < ActiveRecord::Base
274
- acts_as_tree
275
- end
276
- class WhenTag < Tag ; end
277
- class WhereTag < Tag ; end
278
- class WhatTag < Tag ; end
279
- ```
280
-
281
- Please note that Rails (<= 3.2) doesn't handle polymorphic associations correctly if
282
- you use the ```:type``` attribute, so **this doesn't work**:
283
-
284
- ```ruby
285
- # BAD: ActiveRecord ignores the :type attribute:
286
- root.children.create(:name => "child", :type => "WhenTag")
287
- ```
288
-
289
- Instead, use either ```.add_child``` or ```children <<```:
290
-
291
- ```ruby
292
- # GOOD!
293
- a = Tag.create!(:name => "a")
294
- b = WhenTag.new(:name => "b")
295
- a.children << b
296
- c = WhatTag.new(:name => "c")
297
- b.add_child(c)
298
- ```
299
-
300
- See [issue 43](https://github.com/mceachen/closure_tree/issues/43) for more information.
301
-
302
- ## Deterministic ordering
303
-
304
- By default, children will be ordered by your database engine, which may not be what you want.
305
-
306
- If you want to order children alphabetically, and your model has a ```name``` column, you'd do this:
307
-
308
- ```ruby
309
- class Tag < ActiveRecord::Base
310
- acts_as_tree :order => 'name'
311
- end
312
- ```
313
-
314
- If you want a specific order, add a new integer column to your model in a migration:
315
-
316
- ```ruby
317
- t.integer :sort_order
318
- ```
319
-
320
- and in your model:
321
-
322
- ```ruby
323
- class OrderedTag < ActiveRecord::Base
324
- acts_as_tree :order => 'sort_order'
325
- end
326
- ```
327
-
328
- When you enable ```order```, you'll also have the following new methods injected into your model:
329
-
330
- * ```tag.siblings_before``` is a scope containing all nodes with the same parent as ```tag```,
331
- whose sort order column is less than ```self```. These will be ordered properly, so the ```last```
332
- element in scope will be the sibling immediately before ```self```
333
- * ```tag.siblings_after``` is a scope containing all nodes with the same parent as ```tag```,
334
- whose sort order column is more than ```self```. These will be ordered properly, so the ```first```
335
- element in scope will be the sibling immediately "after" ```self```
336
-
337
- If your ```order``` column is an integer attribute, you'll also have these:
338
-
339
- * The class method ```#roots_and_descendants_preordered```, which returns all nodes in your tree,
340
- [pre-ordered](http://en.wikipedia.org/wiki/Tree_traversal#Pre-order).
341
-
342
- * ```node1.self_and_descendants_preordered``` which will return descendants,
343
- [pre-ordered](http://en.wikipedia.org/wiki/Tree_traversal#Pre-order).
344
-
345
- * ```node1.prepend_sibling(node2)``` which will
346
- 1. set ```node2``` to the same parent as ```node1```,
347
- 2. set ```node2```'s order column to 1 less than ```node1```'s value, and
348
- 3. decrement the order_column of all children of node1's parents whose order_column is <>>= node2's new value by 1.
349
-
350
- * ```node1.append_sibling(node2)``` which will
351
- 1. set ```node2``` to the same parent as ```node1```,
352
- 2. set ```node2```'s order column to 1 more than ```node1```'s value, and
353
- 3. increment the order_column of all children of node1's parents whose order_column is >= node2's new value by 1.
354
-
355
- ```ruby
356
-
357
- root = OrderedTag.create(:name => "root")
358
- a = OrderedTag.create(:name => "a", :parent => "root")
359
- b = OrderedTag.create(:name => "b")
360
- c = OrderedTag.create(:name => "c")
361
-
362
- # We have to call 'root.reload.children' because root won't be in sync with the database otherwise:
363
-
364
- a.append_sibling(b)
365
- root.reload.children.collect(&:name)
366
- => ["a", "b"]
367
-
368
- a.prepend_sibling(b)
369
- root.reload.children.collect(&:name)
370
- => ["b", "a"]
371
-
372
- a.append_sibling(c)
373
- root.reload.children.collect(&:name)
374
- => ["b", "a", "c"]
375
-
376
- b.append_sibling(c)
377
- root.reload.children.collect(&:name)
378
- => ["b", "c", "a"]
379
- ```
380
-
381
- ## Concurrency
382
-
383
- Several methods, especially ```#rebuild``` and ```#find_or_create_by_path```, cannot run concurrently correctly.
384
- ```#find_or_create_by_path```, for example, may create duplicate nodes.
385
-
386
- Database row-level locks work correctly with PostgreSQL, but MySQL's row-level locking is broken, and
387
- erroneously reports deadlocks where there are none. To work around this, and have a consistent implementation
388
- for both MySQL and PostgreSQL, [with_advisory_lock](https://github.com/mceachen/with_advisory_lock)
389
- is used automatically to ensure correctness.
390
-
391
- If you are already managing concurrency elsewhere in your application, and want to disable the use
392
- of with_advisory_lock, pass ```:with_advisory_lock => false``` in the options hash:
393
-
394
- ```ruby
395
- class Tag
396
- acts_as_tree :with_advisory_lock => false
397
- end
398
- ```
399
-
400
- Note that you *will eventually have data corruption* if you disable advisory locks, write to your
401
- database with multiple threads, and don't provide an alternative mutex.
402
-
403
-
404
- ## FAQ
405
-
406
- ### Does this gem support multiple parents?
407
-
408
- No. This gem's API is based on the assumption that each node has either 0 or 1 parent.
409
-
410
- The underlying closure tree structure will support multiple parents, but there would be many
411
- breaking-API changes to support it. I'm open to suggestions and pull requests.
412
-
413
- ### How do I use this with test fixtures?
414
-
415
- Test fixtures aren't going to be running your ```after_save``` hooks after inserting all your
416
- fixture data, so you need to call ```.rebuild!``` before your test runs. There's an example in
417
- the spec ```tag_spec.rb```:
418
-
419
- ```ruby
420
- describe "Tag with fixtures" do
421
- fixtures :tags
422
- before :each do
423
- Tag.rebuild! # <- required if you use fixtures
424
- end
425
- ```
426
-
427
- **However, if you're just starting with Rails, may I humbly suggest you adopt a factory library**,
428
- rather than using fixtures? [Lots of people have written about this already](https://www.google.com/search?q=fixtures+versus+factories).
429
-
430
-
431
- ## Testing
432
-
433
- Closure tree is [tested under every combination](http://travis-ci.org/#!/mceachen/closure_tree) of
434
-
435
- * Ruby 1.8.7 and Ruby 1.9.3
436
- * The latest Rails 3.0, 3.1, and 3.2 branches, and
437
- * MySQL and PostgreSQL. SQLite works in a single-threaded environment.
438
-
439
- Assuming you're using [rbenv](https://github.com/sstephenson/rbenv), you can use ```tests.sh``` to
440
- run the test matrix locally.
441
-
442
- Parallelism is not tested with Rails 3.0.x nor 3.1.x due to this
443
- [known issue](https://github.com/rails/rails/issues/7538).
444
-
445
- ## Change log
446
-
447
- ### 3.10.0
448
-
449
- * Added ```#roots_and_descendants_preordered```.
450
- Thanks for the suggestion, [Leonel Galan](https://github.com/leonelgalan)!
451
-
452
- ### 3.9.0
453
-
454
- * Added ```.child_ids```.
455
- * Removed ```dependent => destroy``` on the descendant_hierarchy and ancestor_hierarchy collections
456
- (they were a mistake).
457
- * Clarified documentation for creation and child associations.
458
- Because ```Tag.create!(:parent => ...)``` requires a ```.reload```, I removed it as an example.
459
-
460
- All three of these improvements were suggested by Andrew Bromwich. Thanks!
461
-
462
- ### 3.8.2
463
-
464
- * find_by_path uses 1 SELECT now. BOOM.
465
-
466
- ### 3.8.1
467
-
468
- * Double-check locking for find_or_create_by_path
469
-
470
- ### 3.8.0
471
-
472
- * Support for preordered descendants. This requires a numeric sort order column.
473
- Resolves [feature request 38](https://github.com/mceachen/closure_tree/issues/38).
474
- * Moved modules from ```acts_as_tree``` into separate files
475
-
476
- ### 3.7.3
477
-
478
- Due to MySQL's inability to lock rows properly, I've switched to advisory_locks for
479
- all write paths. This will prevent deadlocks, addressing
480
- [issue 41](https://github.com/mceachen/closure_tree/issues/41).
481
-
482
- ### 3.7.2
483
-
484
- * Support for UUID primary keys. Addresses
485
- [issue 40](https://github.com/mceachen/closure_tree/issues/40). Thanks for the pull request,
486
- [Julien](https://github.com/calexicoz)!
487
-
488
- ### 3.7.1
489
-
490
- * Moved requires into ActiveSupport.on_load
491
- * Added ```require 'with_advisory_lock'```
492
-
493
- ### 3.7.0
494
-
495
- **Thread safety!**
496
- * [Advisory locks](https://github.com/mceachen/with_advisory_lock) were
497
- integrated with the class-level ```find_or_create_by_path``` and ```rebuild!```.
498
- * Pessimistic locking is used by the instance-level ```find_or_create_by_path```.
499
-
500
- ### 3.6.9
501
-
502
- * [Don Morrison](https://github.com/elskwid) massaged the [#hash_tree](#nested-hashes) query to
503
- be more efficient, and found a bug in ```hash_tree```'s query that resulted in duplicate rows,
504
- wasting time on the ruby side.
505
-
506
- ### 3.6.7
507
-
508
- * Added workaround for ActiveRecord::Observer usage pre-db-creation. Addresses
509
- [issue 32](https://github.com/mceachen/closure_tree/issues/32).
510
- Thanks, [Don Morrison](https://github.com/elskwid)!
511
-
512
- ### 3.6.6
513
-
514
- * Added support for Rails 4's [strong parameter](https://github.com/rails/strong_parameters).
515
- Thanks, [James Miller](https://github.com/bensie)!
516
-
517
- ### 3.6.5
518
-
519
- * Use ```quote_table_name``` instead of ```quote_column_name```. Addresses
520
- [issue 29](https://github.com/mceachen/closure_tree/issues/29). Thanks,
521
- [Marcello Barnaba](https://github.com/vjt)!
522
-
523
- ### 3.6.4
524
-
525
- * Use ```.pluck``` when available for ```.ids_from```. Addresses
526
- [issue 26](https://github.com/mceachen/closure_tree/issues/26). Thanks,
527
- [Chris Sturgill](https://github.com/sturgill)!
528
-
529
- ### 3.6.3
530
-
531
- * Fixed [issue 24](https://github.com/mceachen/closure_tree/issues/24), which optimized ```#hash_tree```
532
- for roots. Thanks, [Saverio Trioni](https://github.com/rewritten)!
533
-
534
- ### 3.6.2
535
-
536
- * Fixed [issue 23](https://github.com/mceachen/closure_tree/issues/23), which added support for ```#siblings```
537
- when sort_order wasn't specified. Thanks, [Gary Greyling](https://github.com/garygreyling)!
538
-
539
- ### 3.6.1
540
-
541
- * Fixed [issue 20](https://github.com/mceachen/closure_tree/issues/20), which affected
542
- deterministic ordering when siblings where different STI classes. Thanks, [edwinramirez](https://github.com/edwinramirez)!
543
-
544
- ### 3.6.0
545
-
546
- Added support for:
547
- * ```:hierarchy_class_name``` as an option
548
- * ActiveRecord::Base.table_name_prefix
549
- * ActiveRecord::Base.table_name_suffix
550
-
551
- This addresses [issue 21](https://github.com/mceachen/closure_tree/issues/21). Thanks, [Judd Blair](https://github.com/juddblair)!
552
-
553
- ### 3.5.2
554
-
555
- * Added ```find_all_by_generation```
556
- for [feature request 17](https://github.com/mceachen/closure_tree/issues/17).
557
-
558
- ### 3.4.2
559
-
560
- * Fixed [issue 18](https://github.com/mceachen/closure_tree/issues/18), which affected
561
- append_node/prepend_node ordering when the first node didn't have an explicit order_by value
562
-
563
- ### 3.4.1
564
-
565
- * Reverted .gemspec mistake that changed add_development_dependency to add_runtime_dependency
566
-
567
- ### 3.4.0
568
-
569
- Fixed [issue 15](https://github.com/mceachen/closure_tree/issues/15):
570
- * "parent" is now attr_accessible, which adds support for constructor-provided parents.
571
- * updated readme accordingly
572
-
573
- ### 3.3.2
574
-
575
- * Merged calebphillips' patch for a more efficient leaves query
576
-
577
- ### 3.3.1
578
-
579
- * Added support for partially-unsaved hierarchies [issue 13](https://github.com/mceachen/closure_tree/issues/13):
580
- ```
581
- a = Tag.new(name: "a")
582
- b = Tag.new(name: "b")
583
- a.children << b
584
- a.save
585
- ```
586
-
587
- ### 3.3.0
588
-
589
- * Added [```hash_tree```](#nested-hashes).
590
-
591
- ### 3.2.1
592
-
593
- * Added ```ancestor_ids```, ```descendant_ids```, and ```sibling_ids```
594
- * Added example spec to solve [issue 9](https://github.com/mceachen/closure_tree/issues/9)
595
-
596
- ### 3.2.0
597
-
598
- * Added support for deterministic ordering of nodes.
599
-
600
- ### 3.1.0
601
-
602
- * Switched to using ```has_many :though``` rather than ```has_and_belongs_to_many```
603
-
604
- ### 3.0.4
605
-
606
- * Merged [pull request](https://github.com/mceachen/closure_tree/pull/8) to fix ```.siblings``` and ```.self_and_siblings```
607
- (Thanks, [eljojo](https://github.com/eljojo)!)
608
-
609
- ### 3.0.3
610
-
611
- * Added support for ActiveRecord's whitelist_attributes
612
- (Make sure you read [the Rails Security Guide](http://guides.rubyonrails.org/security.html), and
613
- enable ```config.active_record.whitelist_attributes``` in your ```config/application.rb``` ASAP!)
614
-
615
- ### 3.0.2
616
-
617
- * Fix for ancestry-loop detection (performed by a validation, not through raising an exception in before_save)
618
-
619
- ### 3.0.1
620
-
621
- * Support 3.2.0's fickle deprecation of InstanceMethods (Thanks, [jheiss](https://github.com/mceachen/closure_tree/pull/5))!
622
-
623
- ### 3.0.0
624
-
625
- * Support for polymorphic trees
626
- * ```find_by_path``` and ```find_or_create_by_path``` signatures changed to support constructor attributes
627
- * tested against Rails 3.1.3
628
-
629
- ### 2.0.0
630
-
631
- * 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.
632
- * Tag deletion is supported now along with ```:dependent => :destroy``` and ```:dependent => :delete_all```
633
- * Switched from default rails plugin directory structure to rspec
634
- * Support for running specs under different database engines: ```export DB ; for DB in sqlite3 mysql postgresql ; do rake ; done```
635
-
636
- ## Thanks to
637
-
638
- * https://github.com/collectiveidea/awesome_nested_set
639
- * https://github.com/patshaughnessy/class_factory
640
- * JetBrains, which provides an [open-source license](http://www.jetbrains.com/ruby/buy/buy.jsp#openSource) to
641
- [RubyMine](http://www.jetbrains.com/ruby/features/) for the development of this project.
@@ -1,26 +0,0 @@
1
- begin
2
- require 'bundler/setup'
3
- rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
- end
6
-
7
- Bundler::GemHelper.install_tasks
8
-
9
- require 'yard'
10
- YARD::Rake::YardocTask.new do |t|
11
- t.files = ['lib/**/*.rb', 'README.md']
12
- end
13
-
14
- require "rspec/core/rake_task"
15
- RSpec::Core::RakeTask.new(:spec)
16
-
17
- task :default => :spec
18
-
19
- task :specs_with_db_ixes do
20
- [["", ""], ["db_prefix_", ""], ["", "_db_suffix"], ["abc_", "_123"]].each do |prefix, suffix|
21
- fail unless system("rake spec DB_PREFIX=#{prefix} DB_SUFFIX=#{suffix}")
22
- end
23
- end
24
-
25
- # Run the specs using all the different database engines:
26
- # for DB in sqlite3 mysql postgresql ; do rake ; done
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
- gemspec :path => '..'
3
-
4
- gem 'activerecord', '~> 3.0.0'
5
- gem 'mysql2', '< 0.3.0' # See https://github.com/brianmario/mysql2/issues/155
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
- gemspec :path => '..'
3
-
4
- gem 'activerecord', '~> 3.1.0'
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
- gemspec :path => '..'
3
-
4
- gem 'activerecord', '~> 3.2.0'