acts_as_tree 2.4.0 → 2.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 +4 -4
- data/README.md +2 -0
- data/gemfiles/rails-3.0.gemfile +1 -0
- data/gemfiles/rails-3.1.gemfile +1 -0
- data/gemfiles/rails-3.2.gemfile +1 -0
- data/gemfiles/rails-4.0.gemfile +1 -0
- data/gemfiles/rails-4.1.gemfile +1 -0
- data/gemfiles/rails-4.2.gemfile +1 -0
- data/lib/acts_as_tree.rb +9 -3
- data/lib/acts_as_tree/version.rb +1 -1
- data/test/acts_as_tree_test.rb +75 -72
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a8e94e638a5ea09d242e3a9d5fde5e1f138d88b
|
4
|
+
data.tar.gz: 7f119917e8d1009117adee5394a2538f54a6a3bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86ff17779db508f61f859d16dd6cf1f4385762df0b526ddf7025d22bd829527d1dedd98ea2533b43e563101f5c4fe692e83c2b1e3be032ed40ff1214833e666e
|
7
|
+
data.tar.gz: d21c5cdcc35a15a87527c1633a628be1f17f69f0fe8acb4c9b7f2b1934d019a2de233707a631be39bd35ac26dfda16197f56d25b5ac2568f8d2080911ee5a9f3
|
data/README.md
CHANGED
@@ -74,6 +74,8 @@ We no longer support Ruby 1.8 or versions of Rails/ActiveRecord older than 3.0.
|
|
74
74
|
Moving forward we will do our best to support the latest versions of ActiveRecord and Ruby.
|
75
75
|
|
76
76
|
## Change Log
|
77
|
+
* 2.5.0 - August 14, 2016
|
78
|
+
* Allow for use of a different primary key, see #50 -- Two9A
|
77
79
|
* 2.4.0 - January 12, 2016
|
78
80
|
* Added support for rails 5.0, see #46 -- klacointe
|
79
81
|
* 2.3.0 - November 6, 2015
|
data/gemfiles/rails-3.0.gemfile
CHANGED
data/gemfiles/rails-3.1.gemfile
CHANGED
data/gemfiles/rails-3.2.gemfile
CHANGED
data/gemfiles/rails-4.0.gemfile
CHANGED
data/gemfiles/rails-4.1.gemfile
CHANGED
data/gemfiles/rails-4.2.gemfile
CHANGED
data/lib/acts_as_tree.rb
CHANGED
@@ -54,6 +54,8 @@ module ActsAsTree
|
|
54
54
|
module ClassMethods
|
55
55
|
# Configuration options are:
|
56
56
|
#
|
57
|
+
# * <tt>primary_key</tt> - specifies the column name for relations
|
58
|
+
# (default: +id+)
|
57
59
|
# * <tt>foreign_key</tt> - specifies the column name to use for tracking
|
58
60
|
# of the tree (default: +parent_id+)
|
59
61
|
# * <tt>order</tt> - makes it possible to sort the children according to
|
@@ -63,6 +65,7 @@ module ActsAsTree
|
|
63
65
|
# a custom column by passing a symbol or string.
|
64
66
|
def acts_as_tree(options = {})
|
65
67
|
configuration = {
|
68
|
+
primary_key: primary_key,
|
66
69
|
foreign_key: "parent_id",
|
67
70
|
order: nil,
|
68
71
|
counter_cache: nil,
|
@@ -78,6 +81,7 @@ module ActsAsTree
|
|
78
81
|
|
79
82
|
belongs_to_opts = {
|
80
83
|
class_name: name,
|
84
|
+
primary_key: configuration[:primary_key],
|
81
85
|
foreign_key: configuration[:foreign_key],
|
82
86
|
counter_cache: configuration[:counter_cache],
|
83
87
|
touch: configuration[:touch],
|
@@ -91,11 +95,13 @@ module ActsAsTree
|
|
91
95
|
if ActiveRecord::VERSION::MAJOR >= 4
|
92
96
|
has_many :children, lambda { order configuration[:order] },
|
93
97
|
class_name: name,
|
98
|
+
primary_key: configuration[:primary_key],
|
94
99
|
foreign_key: configuration[:foreign_key],
|
95
100
|
dependent: configuration[:dependent],
|
96
101
|
inverse_of: :parent
|
97
102
|
else
|
98
103
|
has_many :children, class_name: name,
|
104
|
+
primary_key: configuration[:primary_key],
|
99
105
|
foreign_key: configuration[:foreign_key],
|
100
106
|
order: configuration[:order],
|
101
107
|
dependent: configuration[:dependent],
|
@@ -135,7 +141,7 @@ module ActsAsTree
|
|
135
141
|
class_eval <<-EOV
|
136
142
|
def self.leaves
|
137
143
|
internal_ids = select(:#{configuration[:foreign_key]}).where(arel_table[:#{configuration[:foreign_key]}].not_eq(nil))
|
138
|
-
where("
|
144
|
+
where("\#{connection.quote_column_name('#{configuration[:primary_key]}')} NOT IN (\#{internal_ids.to_sql})").default_tree_order
|
139
145
|
end
|
140
146
|
EOV
|
141
147
|
end
|
@@ -216,12 +222,12 @@ module ActsAsTree
|
|
216
222
|
|
217
223
|
def walk_tree_bfs(where = {}, node = nil, level = -1, &block)
|
218
224
|
nodes = (node.nil? ? roots : node.children).where(where)
|
219
|
-
nodes.each { |child|
|
225
|
+
nodes.each { |child| yield(child, level + 1) }
|
220
226
|
nodes.each { |child| walk_tree_bfs where, child, level + 1, &block }
|
221
227
|
end
|
222
228
|
|
223
229
|
def walk_tree_dfs(where = {}, node = nil, level = -1, &block)
|
224
|
-
|
230
|
+
yield(node, level) unless level == -1
|
225
231
|
nodes = (node.nil? ? roots : node.children).where(where)
|
226
232
|
nodes.each { |child| walk_tree_dfs where, child, level + 1, &block }
|
227
233
|
end
|
data/lib/acts_as_tree/version.rb
CHANGED
data/test/acts_as_tree_test.rb
CHANGED
@@ -47,29 +47,27 @@ end
|
|
47
47
|
|
48
48
|
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
49
49
|
|
50
|
-
def setup_db(
|
50
|
+
def setup_db(options = {})
|
51
51
|
# AR keeps printing annoying schema statements
|
52
52
|
capture_stdout do
|
53
53
|
ActiveRecord::Base.logger
|
54
54
|
ActiveRecord::Schema.define(version: 1) do
|
55
|
-
create_table :mixins do |t|
|
55
|
+
create_table :mixins, force: true do |t|
|
56
56
|
t.column :type, :string
|
57
57
|
t.column :parent_id, :integer
|
58
|
-
t.column
|
58
|
+
t.column :external_id, :integer if options[:external_ids]
|
59
|
+
t.column :external_parent_id, :integer if options[:external_ids]
|
60
|
+
t.column :children_count, :integer, default: 0 if options[:counter_cache]
|
59
61
|
t.timestamps null: false
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
def teardown_db
|
68
|
-
# Silence tables deprecation on rails 5.0
|
69
|
-
ActiveSupport::Deprecation.silence do
|
70
|
-
ActiveRecord::Base.connection.tables.each do |table|
|
71
|
-
ActiveRecord::Base.connection.drop_table(table)
|
65
|
+
# Fix broken reset_column_information in some activerecord versions.
|
66
|
+
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 2 ||
|
67
|
+
ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 1
|
68
|
+
ActiveRecord::Base.connection.schema_cache.clear!
|
72
69
|
end
|
70
|
+
Mixin.reset_column_information
|
73
71
|
end
|
74
72
|
end
|
75
73
|
|
@@ -99,25 +97,30 @@ class RecursivelyCascadedTreeMixin < Mixin
|
|
99
97
|
end
|
100
98
|
|
101
99
|
class TreeMixinWithTouch < Mixin
|
102
|
-
|
100
|
+
acts_as_tree foreign_key: "parent_id", order: "id", touch: true
|
101
|
+
end
|
102
|
+
|
103
|
+
class ExternalTreeMixin < Mixin
|
104
|
+
acts_as_tree foreign_key: "external_parent_id", primary_key: "external_id"
|
105
|
+
end
|
106
|
+
|
107
|
+
class ExternalTreeMixinNullify < Mixin
|
108
|
+
acts_as_tree foreign_key: "external_parent_id", primary_key: "external_id", order: "id", dependent: :nullify
|
103
109
|
end
|
104
110
|
|
105
111
|
class TreeTest < ActsAsTreeTestCase
|
106
112
|
|
107
113
|
def setup
|
108
114
|
setup_db
|
115
|
+
@tree_mixin = TreeMixin
|
109
116
|
|
110
|
-
@root1 =
|
111
|
-
@root_child1 =
|
112
|
-
@child1_child =
|
113
|
-
@child1_child_child =
|
114
|
-
@root_child2 =
|
115
|
-
@root2 =
|
116
|
-
@root3 =
|
117
|
-
end
|
118
|
-
|
119
|
-
def teardown
|
120
|
-
teardown_db
|
117
|
+
@root1 = @tree_mixin.create!
|
118
|
+
@root_child1 = @tree_mixin.create! parent_id: @root1.id
|
119
|
+
@child1_child = @tree_mixin.create! parent_id: @root_child1.id
|
120
|
+
@child1_child_child = @tree_mixin.create! parent_id: @child1_child.id
|
121
|
+
@root_child2 = @tree_mixin.create! parent_id: @root1.id
|
122
|
+
@root2 = @tree_mixin.create!
|
123
|
+
@root3 = @tree_mixin.create!
|
121
124
|
end
|
122
125
|
|
123
126
|
def test_children
|
@@ -135,12 +138,12 @@ class TreeTest < ActsAsTreeTestCase
|
|
135
138
|
end
|
136
139
|
|
137
140
|
def test_delete
|
138
|
-
assert_equal 7,
|
141
|
+
assert_equal 7, @tree_mixin.count
|
139
142
|
@root1.destroy
|
140
|
-
assert_equal 2,
|
143
|
+
assert_equal 2, @tree_mixin.count
|
141
144
|
@root2.destroy
|
142
145
|
@root3.destroy
|
143
|
-
assert_equal 0,
|
146
|
+
assert_equal 0, @tree_mixin.count
|
144
147
|
end
|
145
148
|
|
146
149
|
def test_insert
|
@@ -166,7 +169,7 @@ class TreeTest < ActsAsTreeTestCase
|
|
166
169
|
end
|
167
170
|
|
168
171
|
def test_root
|
169
|
-
assert_equal @root1,
|
172
|
+
assert_equal @root1, @tree_mixin.root
|
170
173
|
assert_equal @root1, @root1.root
|
171
174
|
assert_equal @root1, @root_child1.root
|
172
175
|
assert_equal @root1, @child1_child.root
|
@@ -176,15 +179,15 @@ class TreeTest < ActsAsTreeTestCase
|
|
176
179
|
end
|
177
180
|
|
178
181
|
def test_roots
|
179
|
-
assert_equal [@root1, @root2, @root3],
|
182
|
+
assert_equal [@root1, @root2, @root3], @tree_mixin.roots
|
180
183
|
end
|
181
184
|
|
182
185
|
def test_leaves
|
183
|
-
assert_equal [@child1_child_child, @root_child2, @root2, @root3],
|
186
|
+
assert_equal [@child1_child_child, @root_child2, @root2, @root3], @tree_mixin.leaves
|
184
187
|
end
|
185
188
|
|
186
189
|
def test_default_tree_order
|
187
|
-
assert_equal [@root1, @root_child1, @child1_child, @child1_child_child, @root_child2, @root2, @root3],
|
190
|
+
assert_equal [@root1, @root_child1, @child1_child, @child1_child_child, @root_child2, @root2, @root3], @tree_mixin.default_tree_order
|
188
191
|
end
|
189
192
|
|
190
193
|
def test_siblings
|
@@ -261,9 +264,9 @@ class TreeTest < ActsAsTreeTestCase
|
|
261
264
|
end
|
262
265
|
|
263
266
|
def test_tree_view
|
264
|
-
assert_equal false,
|
265
|
-
|
266
|
-
assert_equal true,
|
267
|
+
assert_equal false, @tree_mixin.respond_to?(:tree_view)
|
268
|
+
@tree_mixin.extend ActsAsTree::TreeView
|
269
|
+
assert_equal true, @tree_mixin.respond_to?(:tree_view)
|
267
270
|
|
268
271
|
tree_view_outputs = <<-END.gsub(/^ {6}/, '')
|
269
272
|
root
|
@@ -275,15 +278,15 @@ class TreeTest < ActsAsTreeTestCase
|
|
275
278
|
|_ 6
|
276
279
|
|_ 7
|
277
280
|
END
|
278
|
-
assert_equal tree_view_outputs, capture_stdout {
|
281
|
+
assert_equal tree_view_outputs, capture_stdout { @tree_mixin.tree_view(:id) }
|
279
282
|
end
|
280
283
|
|
281
284
|
def test_tree_walker
|
282
|
-
assert_equal false,
|
283
|
-
assert_equal false,
|
284
|
-
|
285
|
-
assert_equal true,
|
286
|
-
assert_equal true,
|
285
|
+
assert_equal false, @tree_mixin.respond_to?(:walk_tree)
|
286
|
+
assert_equal false, @tree_mixin.new.respond_to?(:walk_tree)
|
287
|
+
@tree_mixin.extend ActsAsTree::TreeWalker
|
288
|
+
assert_equal true, @tree_mixin.respond_to?(:walk_tree)
|
289
|
+
assert_equal true, @tree_mixin.new.respond_to?(:walk_tree)
|
287
290
|
|
288
291
|
walk_tree_dfs_output = <<-END.gsub(/^\s+/, '')
|
289
292
|
1
|
@@ -294,7 +297,7 @@ class TreeTest < ActsAsTreeTestCase
|
|
294
297
|
6
|
295
298
|
7
|
296
299
|
END
|
297
|
-
assert_equal walk_tree_dfs_output, capture_stdout {
|
300
|
+
assert_equal walk_tree_dfs_output, capture_stdout { @tree_mixin.walk_tree{|elem, level| puts "#{'-'*level}#{elem.id}"} }
|
298
301
|
|
299
302
|
walk_tree_dfs_sub_output = <<-END.gsub(/^\s+/, '')
|
300
303
|
2
|
@@ -313,7 +316,7 @@ class TreeTest < ActsAsTreeTestCase
|
|
313
316
|
--3
|
314
317
|
---4
|
315
318
|
END
|
316
|
-
assert_equal walk_tree_bfs_output, capture_stdout {
|
319
|
+
assert_equal walk_tree_bfs_output, capture_stdout { @tree_mixin.walk_tree(:algorithm => :bfs){|elem, level| puts "#{'-'*level}#{elem.id}"} }
|
317
320
|
|
318
321
|
walk_tree_bfs_sub_output = <<-END.gsub(/^\s+/, '')
|
319
322
|
2
|
@@ -327,7 +330,6 @@ end
|
|
327
330
|
|
328
331
|
class TestDeepDescendantsPerformance < ActsAsTreeTestCase
|
329
332
|
def setup
|
330
|
-
teardown_db
|
331
333
|
setup_db
|
332
334
|
@root1 = TreeMixin.create!
|
333
335
|
create_cascade_children @root1, "root1", 10
|
@@ -345,10 +347,6 @@ class TestDeepDescendantsPerformance < ActsAsTreeTestCase
|
|
345
347
|
create_cascade_children @root5, "root5", 50
|
346
348
|
end
|
347
349
|
|
348
|
-
def teardown
|
349
|
-
teardown_db
|
350
|
-
end
|
351
|
-
|
352
350
|
def self.bench_range
|
353
351
|
[1, 2, 3, 4, 5]
|
354
352
|
end
|
@@ -378,7 +376,6 @@ end
|
|
378
376
|
class TreeTestWithEagerLoading < ActsAsTreeTestCase
|
379
377
|
|
380
378
|
def setup
|
381
|
-
teardown_db
|
382
379
|
setup_db
|
383
380
|
@root1 = TreeMixin.create!
|
384
381
|
@root_child1 = TreeMixin.create! parent_id: @root1.id
|
@@ -393,10 +390,6 @@ class TreeTestWithEagerLoading < ActsAsTreeTestCase
|
|
393
390
|
@rc4 = RecursivelyCascadedTreeMixin.create! parent_id: @rc3.id
|
394
391
|
end
|
395
392
|
|
396
|
-
def teardown
|
397
|
-
teardown_db
|
398
|
-
end
|
399
|
-
|
400
393
|
def test_eager_association_loading
|
401
394
|
roots = TreeMixin.includes(:children)
|
402
395
|
.where('mixins.parent_id IS NULL')
|
@@ -444,10 +437,6 @@ class TreeTestWithoutOrder < ActsAsTreeTestCase
|
|
444
437
|
@root2 = TreeMixinWithoutOrder.create!
|
445
438
|
end
|
446
439
|
|
447
|
-
def teardown
|
448
|
-
teardown_db
|
449
|
-
end
|
450
|
-
|
451
440
|
def test_root
|
452
441
|
assert [@root1, @root2].include? TreeMixinWithoutOrder.root
|
453
442
|
end
|
@@ -464,10 +453,6 @@ class UnsavedTreeTest < ActsAsTreeTestCase
|
|
464
453
|
@root_child = @root.children.build
|
465
454
|
end
|
466
455
|
|
467
|
-
def teardown
|
468
|
-
teardown_db
|
469
|
-
end
|
470
|
-
|
471
456
|
def test_inverse_of
|
472
457
|
# We want children to be aware of their parent before saving either
|
473
458
|
assert_equal @root, @root_child.parent
|
@@ -477,8 +462,7 @@ end
|
|
477
462
|
|
478
463
|
class TreeTestWithCounterCache < ActsAsTreeTestCase
|
479
464
|
def setup
|
480
|
-
|
481
|
-
setup_db(true)
|
465
|
+
setup_db counter_cache: true
|
482
466
|
|
483
467
|
@root = TreeMixinWithCounterCache.create!
|
484
468
|
@child1 = TreeMixinWithCounterCache.create! parent_id: @root.id
|
@@ -488,10 +472,6 @@ class TreeTestWithCounterCache < ActsAsTreeTestCase
|
|
488
472
|
[@root, @child1, @child1_child1, @child2].map(&:reload)
|
489
473
|
end
|
490
474
|
|
491
|
-
def teardown
|
492
|
-
teardown_db
|
493
|
-
end
|
494
|
-
|
495
475
|
def test_counter_cache
|
496
476
|
assert_equal 2, @root.children_count
|
497
477
|
assert_equal 1, @child1.children_count
|
@@ -519,22 +499,45 @@ end
|
|
519
499
|
|
520
500
|
class TreeTestWithTouch < ActsAsTreeTestCase
|
521
501
|
def setup
|
522
|
-
teardown_db
|
523
502
|
setup_db
|
524
503
|
|
525
504
|
@root = TreeMixinWithTouch.create!
|
526
505
|
@child = TreeMixinWithTouch.create! parent_id: @root.id
|
527
506
|
end
|
528
507
|
|
529
|
-
def teardown
|
530
|
-
teardown_db
|
531
|
-
end
|
532
|
-
|
533
508
|
def test_updated_at
|
534
509
|
previous_root_updated_at = @root.updated_at
|
535
510
|
@child.update_attributes(:type => "new_type")
|
536
511
|
@root.reload
|
537
|
-
|
512
|
+
|
538
513
|
assert @root.updated_at != previous_root_updated_at
|
539
514
|
end
|
540
515
|
end
|
516
|
+
|
517
|
+
class ExternalTreeTest < TreeTest
|
518
|
+
def setup
|
519
|
+
setup_db external_ids: true
|
520
|
+
@tree_mixin = ExternalTreeMixin
|
521
|
+
|
522
|
+
@root1 = @tree_mixin.create! external_id: 1101
|
523
|
+
@root_child1 = @tree_mixin.create! external_id: 1102, external_parent_id: @root1.external_id
|
524
|
+
@child1_child = @tree_mixin.create! external_id: 1103, external_parent_id: @root_child1.external_id
|
525
|
+
@child1_child_child = @tree_mixin.create! external_id: 1104, external_parent_id: @child1_child.external_id
|
526
|
+
@root_child2 = @tree_mixin.create! external_id: 1105, external_parent_id: @root1.external_id
|
527
|
+
@root2 = @tree_mixin.create! external_id: 1106
|
528
|
+
@root3 = @tree_mixin.create! external_id: 1107
|
529
|
+
end
|
530
|
+
|
531
|
+
def test_nullify
|
532
|
+
root4 = ExternalTreeMixinNullify.create! external_id: 1108
|
533
|
+
root4_child = ExternalTreeMixinNullify.create! external_id: 1109, external_parent_id: root4.external_id
|
534
|
+
|
535
|
+
assert_equal 2, ExternalTreeMixinNullify.count
|
536
|
+
assert_equal root4.external_id, root4_child.external_parent_id
|
537
|
+
|
538
|
+
root4.destroy
|
539
|
+
|
540
|
+
assert_equal 1, ExternalTreeMixinNullify.count
|
541
|
+
assert_nil root4_child.reload.external_parent_id
|
542
|
+
end
|
543
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erik Dahlstrand
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2016-
|
15
|
+
date: 2016-08-14 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activerecord
|