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 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, y| x.name.downcase <=> y.name.downcase} %>
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
+ 1.6.2
@@ -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.
@@ -21,7 +21,10 @@ module CollectiveIdea #:nodoc:
21
21
 
22
22
  # Update cached_level attribute
23
23
  def update_depth
24
- self.update_attribute(:depth, level)
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
@@ -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,y| x.name.mb_chars.downcase <=> y.name.mb_chars.downcase}
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
- class_or_item = class_or_item.roots if class_or_item.is_a?(Class)
66
- items = Array(class_or_item)
67
- result = []
68
- items.sort_by(&sort_proc).each do |item|
69
- hash = item.self_and_descendants.arrange
70
- result += build_node(hash, sort_proc, mover, level){|x, lvl| yield(x, lvl)}
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 << [yield(node, level.to_i), node.id]
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?
@@ -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.1"
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-11}
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 = [
@@ -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(&:name)){|i, level| "#{'-' * level} #{i.name}" }
52
+ sorted_nested_set_options(Category, lambda{|x| x.name }){|i, level| "#{'-' * level} #{i.name}" }
53
53
  end
54
54
 
55
55
  end
@@ -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
@@ -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 test_left_column_name
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
- - 1
9
- version: 1.6.1
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-11 00:00:00 +03:00
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: -134095791
156
+ hash: 754987949
157
157
  segments:
158
158
  - 0
159
159
  version: "0"