nested_set 1.6.1 → 1.6.2
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.
- data/README.md +1 -1
- data/VERSION +1 -1
- data/lib/nested_set/base.rb +10 -0
- data/lib/nested_set/depth.rb +4 -1
- data/lib/nested_set/helper.rb +9 -12
- data/nested_set.gemspec +2 -2
- data/test/benchmarks.rb +1 -1
- data/test/db/schema.rb +4 -3
- data/test/fixtures/categories.yml +6 -0
- data/test/nested_set_test.rb +37 -2
- metadata +4 -4
data/README.md
CHANGED
@@ -66,7 +66,7 @@ or sorted select:
|
|
66
66
|
|
67
67
|
<%= f.select :parent_id, sorted_nested_set_options(Category, lambda(&:name)) {|i, level| "#{'-' * level} #{i.name}" } %>
|
68
68
|
|
69
|
-
<% sort_method = lambda{|x
|
69
|
+
<% sort_method = lambda{|x| x.name.downcase} %>
|
70
70
|
|
71
71
|
NOTE: to sort UTF-8 strings you should use `x.name.mb_chars.downcase`
|
72
72
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.6.
|
1
|
+
1.6.2
|
data/lib/nested_set/base.rb
CHANGED
@@ -28,6 +28,7 @@ module CollectiveIdea #:nodoc:
|
|
28
28
|
# * +:parent_column+ - specifies the column name to use for keeping the position integer (default: parent_id)
|
29
29
|
# * +:left_column+ - column name for left boundry data, default "lft"
|
30
30
|
# * +:right_column+ - column name for right boundry data, default "rgt"
|
31
|
+
# * +:depth_column+ - column name for level cache data, default "depth"
|
31
32
|
# * +:scope+ - restricts what is to be considered a list. Given a symbol, it'll attach "_id"
|
32
33
|
# (if it hasn't been already) and use that as the foreign key restriction. You
|
33
34
|
# can also pass an array to scope by multiple attributes.
|
@@ -45,6 +46,7 @@ module CollectiveIdea #:nodoc:
|
|
45
46
|
:parent_column => 'parent_id',
|
46
47
|
:left_column => 'lft',
|
47
48
|
:right_column => 'rgt',
|
49
|
+
:depth_column => 'depth',
|
48
50
|
:dependent => :delete_all, # or :destroy
|
49
51
|
}.merge(options)
|
50
52
|
|
@@ -287,6 +289,10 @@ module CollectiveIdea #:nodoc:
|
|
287
289
|
Array(acts_as_nested_set_options[:scope])
|
288
290
|
end
|
289
291
|
|
292
|
+
def depth_column_name
|
293
|
+
acts_as_nested_set_options[:depth_column]
|
294
|
+
end
|
295
|
+
|
290
296
|
def quoted_left_column_name
|
291
297
|
connection.quote_column_name(left_column_name)
|
292
298
|
end
|
@@ -302,6 +308,10 @@ module CollectiveIdea #:nodoc:
|
|
302
308
|
def quoted_scope_column_names
|
303
309
|
scope_column_names.collect {|column_name| connection.quote_column_name(column_name) }
|
304
310
|
end
|
311
|
+
|
312
|
+
def quoted_depth_column_name
|
313
|
+
connection.quote_column_name(depth_column_name)
|
314
|
+
end
|
305
315
|
end
|
306
316
|
|
307
317
|
# Any instance method that returns a collection makes use of Rails 2.1's named_scope (which is bundled for Rails 2.0), so it can be treated as a finder.
|
data/lib/nested_set/depth.rb
CHANGED
@@ -21,7 +21,10 @@ module CollectiveIdea #:nodoc:
|
|
21
21
|
|
22
22
|
# Update cached_level attribute
|
23
23
|
def update_depth
|
24
|
-
|
24
|
+
depth_delta = level - depth
|
25
|
+
if depth_delta != 0
|
26
|
+
self.self_and_descendants.update_all(["#{self.class.quoted_depth_column_name} = #{self.class.quoted_depth_column_name} + ?", depth_delta])
|
27
|
+
end
|
25
28
|
end
|
26
29
|
|
27
30
|
# Update cached_level attribute for all record tree
|
data/lib/nested_set/helper.rb
CHANGED
@@ -26,7 +26,6 @@ module CollectiveIdea #:nodoc:
|
|
26
26
|
items = Array(class_or_item)
|
27
27
|
result = []
|
28
28
|
items.each do |item|
|
29
|
-
levels = []
|
30
29
|
item.self_and_descendants.each_with_level do |i, level|
|
31
30
|
if mover.nil? || mover.new_record? || mover.move_possible?(i)
|
32
31
|
result.push([yield(i, level), i.id])
|
@@ -55,28 +54,26 @@ module CollectiveIdea #:nodoc:
|
|
55
54
|
#
|
56
55
|
# OR
|
57
56
|
#
|
58
|
-
# sort_method = lambda{|x
|
57
|
+
# sort_method = lambda{|x| x.name.mb_chars.downcase }
|
59
58
|
#
|
60
59
|
# <%= f.select :parent_id, nested_set_options(Category, sort_method) {|i, level|
|
61
60
|
# "#{'–' * level} #{i.name}"
|
62
61
|
# }) %>
|
63
62
|
#
|
64
63
|
def sorted_nested_set_options(class_or_item, sort_proc, mover = nil, level = 0)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
result
|
64
|
+
hash = if class_or_item.is_a?(Class)
|
65
|
+
class_or_item
|
66
|
+
else
|
67
|
+
class_or_item.self_and_descendants
|
68
|
+
end.arrange
|
69
|
+
build_node(hash, sort_proc, mover, level){|x, lvl| yield(x, lvl)}
|
73
70
|
end
|
74
71
|
|
75
72
|
def build_node(hash, sort_proc, mover = nil, level = nil)
|
76
|
-
result
|
73
|
+
result = []
|
77
74
|
hash.keys.sort_by(&sort_proc).each do |node|
|
78
75
|
if mover.nil? || mover.new_record? || mover.move_possible?(node)
|
79
|
-
result
|
76
|
+
result.push([yield(node, level.to_i), node.id])
|
80
77
|
result.push(*build_node(hash[node], sort_proc, mover, level.to_i + 1){|x, lvl| yield(x, lvl)})
|
81
78
|
end
|
82
79
|
end if hash.present?
|
data/nested_set.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{nested_set}
|
8
|
-
s.version = "1.6.
|
8
|
+
s.version = "1.6.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brandon Keepers", "Daniel Morrison"]
|
12
|
-
s.date = %q{2010-12-
|
12
|
+
s.date = %q{2010-12-23}
|
13
13
|
s.description = %q{An awesome nested set implementation for Active Record}
|
14
14
|
s.email = %q{info@collectiveidea.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/test/benchmarks.rb
CHANGED
@@ -49,7 +49,7 @@ if $0 == __FILE__
|
|
49
49
|
end
|
50
50
|
|
51
51
|
measure "sorted_nested_set_options" do
|
52
|
-
sorted_nested_set_options(Category, lambda
|
52
|
+
sorted_nested_set_options(Category, lambda{|x| x.name }){|i, level| "#{'-' * level} #{i.name}" }
|
53
53
|
end
|
54
54
|
|
55
55
|
end
|
data/test/db/schema.rb
CHANGED
@@ -5,14 +5,14 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
5
5
|
t.column :parent_id, :integer
|
6
6
|
t.column :lft, :integer
|
7
7
|
t.column :rgt, :integer
|
8
|
-
t.column :depth, :integer, :default => 0
|
9
8
|
t.column :organization_id, :integer
|
9
|
+
t.column :depth, :integer, :default => 0
|
10
10
|
end
|
11
11
|
|
12
12
|
create_table :departments, :force => true do |t|
|
13
13
|
t.column :name, :string
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
create_table :notes, :force => true do |t|
|
17
17
|
t.column :body, :text
|
18
18
|
t.column :parent_id, :integer
|
@@ -21,11 +21,12 @@ ActiveRecord::Schema.define(:version => 0) do
|
|
21
21
|
t.column :notable_id, :integer
|
22
22
|
t.column :notable_type, :string
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
create_table :renamed_columns, :force => true do |t|
|
26
26
|
t.column :name, :string
|
27
27
|
t.column :mother_id, :integer
|
28
28
|
t.column :red, :integer
|
29
29
|
t.column :black, :integer
|
30
|
+
t.column :level, :integer
|
30
31
|
end
|
31
32
|
end
|
@@ -14,32 +14,38 @@ top_level:
|
|
14
14
|
name: Top Level
|
15
15
|
lft: 1
|
16
16
|
rgt: 10
|
17
|
+
depth: 0
|
17
18
|
child_1:
|
18
19
|
id: 2
|
19
20
|
name: Child 1
|
20
21
|
parent_id: 1
|
21
22
|
lft: 2
|
22
23
|
rgt: 3
|
24
|
+
depth: 1
|
23
25
|
child_2:
|
24
26
|
id: 3
|
25
27
|
name: Child 2
|
26
28
|
parent_id: 1
|
27
29
|
lft: 4
|
28
30
|
rgt: 7
|
31
|
+
depth: 1
|
29
32
|
child_2_1:
|
30
33
|
id: 4
|
31
34
|
name: Child 2.1
|
32
35
|
parent_id: 3
|
33
36
|
lft: 5
|
34
37
|
rgt: 6
|
38
|
+
depth: 2
|
35
39
|
child_3:
|
36
40
|
id: 5
|
37
41
|
name: Child 3
|
38
42
|
parent_id: 1
|
39
43
|
lft: 8
|
40
44
|
rgt: 9
|
45
|
+
depth: 1
|
41
46
|
top_level_2:
|
42
47
|
id: 6
|
43
48
|
name: Top Level 2
|
44
49
|
lft: 11
|
45
50
|
rgt: 12
|
51
|
+
depth: 0
|
data/test/nested_set_test.rb
CHANGED
@@ -15,7 +15,7 @@ class ScopedCategory < ActiveRecord::Base
|
|
15
15
|
end
|
16
16
|
|
17
17
|
class RenamedColumns < ActiveRecord::Base
|
18
|
-
acts_as_nested_set :parent_column => 'mother_id', :left_column => 'red', :right_column => 'black'
|
18
|
+
acts_as_nested_set :parent_column => 'mother_id', :left_column => 'red', :right_column => 'black', :depth_column => 'level'
|
19
19
|
end
|
20
20
|
|
21
21
|
class NestedSetTest < ActiveSupport::TestCase
|
@@ -32,11 +32,15 @@ class NestedSetTest < ActiveSupport::TestCase
|
|
32
32
|
assert_equal 'parent_id', Default.acts_as_nested_set_options[:parent_column]
|
33
33
|
end
|
34
34
|
|
35
|
+
def test_depth_column_default
|
36
|
+
assert_equal 'depth', Default.acts_as_nested_set_options[:depth_column]
|
37
|
+
end
|
38
|
+
|
35
39
|
def test_scope_default
|
36
40
|
assert_nil Default.acts_as_nested_set_options[:scope]
|
37
41
|
end
|
38
42
|
|
39
|
-
def
|
43
|
+
def test_left_column_default
|
40
44
|
assert_equal 'lft', Default.left_column_name
|
41
45
|
assert_equal 'lft', Default.new.left_column_name
|
42
46
|
assert_equal 'red', RenamedColumns.left_column_name
|
@@ -57,6 +61,13 @@ class NestedSetTest < ActiveSupport::TestCase
|
|
57
61
|
assert_equal 'mother_id', RenamedColumns.new.parent_column_name
|
58
62
|
end
|
59
63
|
|
64
|
+
def test_depth_column_name
|
65
|
+
assert_equal 'depth', Default.depth_column_name
|
66
|
+
assert_equal 'depth', Default.new.depth_column_name
|
67
|
+
assert_equal 'level', RenamedColumns.depth_column_name
|
68
|
+
assert_equal 'level', RenamedColumns.new.depth_column_name
|
69
|
+
end
|
70
|
+
|
60
71
|
def test_creation_with_altered_column_names
|
61
72
|
assert_nothing_raised do
|
62
73
|
RenamedColumns.create!()
|
@@ -75,6 +86,12 @@ class NestedSetTest < ActiveSupport::TestCase
|
|
75
86
|
assert_equal quoted, Default.new.quoted_right_column_name
|
76
87
|
end
|
77
88
|
|
89
|
+
def test_quoted_depth_column_name
|
90
|
+
quoted = Default.connection.quote_column_name('depth')
|
91
|
+
assert_equal quoted, Default.quoted_depth_column_name
|
92
|
+
assert_equal quoted, Default.new.quoted_depth_column_name
|
93
|
+
end
|
94
|
+
|
78
95
|
def test_left_column_protected_from_assignment
|
79
96
|
assert_raises(ActiveRecord::ActiveRecordError) { Category.new.lft = 1 }
|
80
97
|
end
|
@@ -174,6 +191,24 @@ class NestedSetTest < ActiveSupport::TestCase
|
|
174
191
|
assert_equal 2, categories(:child_2_1).level
|
175
192
|
end
|
176
193
|
|
194
|
+
def test_depth
|
195
|
+
assert_equal 0, categories(:top_level).depth
|
196
|
+
assert_equal 1, categories(:child_1).depth
|
197
|
+
assert_equal 2, categories(:child_2_1).depth
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_depth_after_move
|
201
|
+
categories(:child_2).move_to_root
|
202
|
+
|
203
|
+
assert_equal 0, categories(:child_2).reload.depth
|
204
|
+
assert_equal 1, categories(:child_2_1).reload.depth
|
205
|
+
|
206
|
+
categories(:child_2).move_to_child_of(categories(:top_level_2))
|
207
|
+
|
208
|
+
assert_equal 1, categories(:child_2).reload.depth
|
209
|
+
assert_equal 2, categories(:child_2_1).reload.depth
|
210
|
+
end
|
211
|
+
|
177
212
|
def test_has_children?
|
178
213
|
assert categories(:child_2_1).children.empty?
|
179
214
|
assert !categories(:child_2).children.empty?
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 6
|
8
|
-
-
|
9
|
-
version: 1.6.
|
8
|
+
- 2
|
9
|
+
version: 1.6.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Brandon Keepers
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-12-
|
18
|
+
date: 2010-12-23 00:00:00 +03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -153,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
153
153
|
requirements:
|
154
154
|
- - ">="
|
155
155
|
- !ruby/object:Gem::Version
|
156
|
-
hash:
|
156
|
+
hash: 754987949
|
157
157
|
segments:
|
158
158
|
- 0
|
159
159
|
version: "0"
|