acts_as_tree 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|