ramdiv-mongo_mapper_acts_as_tree 0.0.5 → 0.1.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.
data/README.rdoc CHANGED
@@ -21,12 +21,13 @@ Enable the tree functionality by declaring acts_as_tree on your model
21
21
  acts_as_tree
22
22
  end
23
23
 
24
- The method accepts :parent_id_field, :path_field, :depth_field, :order as a hash.
24
+ The method accepts :parent_id_field, :path_field, :depth_field, :order, :search_class as a hash.
25
25
 
26
26
  :parent_id_field, :path_field, :depth_field => override the default field names
27
27
  :order => control the order (format "_field-name_ _[asc|desc]_")
28
+ :search_class => expects a Class that is a MongoMapper::Document to be used for search
28
29
 
29
- Check the test_tree.rb for examples.
30
+ Check test_tree.rb and test_search_class.rb for examples.
30
31
 
31
32
  == About bugs
32
33
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.1.0
@@ -49,7 +49,7 @@ module MongoMapper
49
49
  end
50
50
 
51
51
  def parent=(var)
52
- var = self.class.find(var) if var.is_a? String
52
+ var = search_class.find(var) if var.is_a? String
53
53
 
54
54
  if self.descendants.include? var
55
55
  @_cyclic = true
@@ -79,7 +79,7 @@ module MongoMapper
79
79
  end
80
80
 
81
81
  def parent
82
- @_parent or (self[parent_id_field].nil? ? nil : self.class.find(self[parent_id_field]))
82
+ @_parent or (self[parent_id_field].nil? ? nil : search_class.find(self[parent_id_field]))
83
83
  end
84
84
 
85
85
  def root?
@@ -87,12 +87,12 @@ module MongoMapper
87
87
  end
88
88
 
89
89
  def root
90
- self[path_field].first.nil? ? self : self.class.find(self[path_field].first)
90
+ self[path_field].first.nil? ? self : search_class.find(self[path_field].first)
91
91
  end
92
92
 
93
93
  def ancestors
94
94
  return [] if root?
95
- self.class.find(self[path_field])
95
+ search_class.find(self[path_field])
96
96
  end
97
97
 
98
98
  def self_and_ancestors
@@ -100,20 +100,20 @@ module MongoMapper
100
100
  end
101
101
 
102
102
  def siblings
103
- self.class.all(:_id => {"$ne" => self._id}, parent_id_field => self[parent_id_field], :order => tree_order)
103
+ search_class.all(:_id => {"$ne" => self._id}, parent_id_field => self[parent_id_field], :order => tree_order)
104
104
  end
105
105
 
106
106
  def self_and_siblings
107
- self.class.all(parent_id_field => self[parent_id_field], :order => tree_order)
107
+ search_class.all(parent_id_field => self[parent_id_field], :order => tree_order)
108
108
  end
109
109
 
110
110
  def children
111
- self.class.all(parent_id_field => self._id, :order => tree_order)
111
+ search_class.all(parent_id_field => self._id, :order => tree_order)
112
112
  end
113
113
 
114
114
  def descendants
115
115
  return [] if new_record?
116
- self.class.all(path_field => self._id, :order => tree_order)
116
+ search_class.all(path_field => self._id, :order => tree_order)
117
117
  end
118
118
 
119
119
  def self_and_descendants
@@ -156,7 +156,7 @@ module MongoMapper
156
156
  end
157
157
 
158
158
  def destroy_descendants
159
- self.class.destroy(self.descendants.map(&:_id))
159
+ search_class.destroy(self.descendants.map(&:_id))
160
160
  end
161
161
  end
162
162
 
@@ -176,6 +176,21 @@ module MongoMapper
176
176
  def tree_order
177
177
  acts_as_tree_options[:order] or ""
178
178
  end
179
+
180
+ # When added as an option to acts_as_tree, search class will be used as the base from which to
181
+ # find tree objects. This is handy should you have a tree of objects that are of different types, but
182
+ # might be related through single table inheritance.
183
+ #
184
+ # acts_as_tree :search_class => Shape
185
+ #
186
+ # In the above example, you could have a working tree ofShape, Circle and Square types (assuming
187
+ # Circle and Square were subclasses of Shape). If you want to do the same thing and you don't provide
188
+ # search_class, nesting mixed types will not work.
189
+ #
190
+ # The default is +self.class+
191
+ def search_class
192
+ acts_as_tree_options[:search_class] or self.class
193
+ end
179
194
  end
180
195
  end
181
196
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ramdiv-mongo_mapper_acts_as_tree}
8
- s.version = "0.0.5"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jakob Vidmar"]
12
- s.date = %q{2010-03-27}
12
+ s.date = %q{2010-06-05}
13
13
  s.description = %q{Port of the old, venerable ActsAsTree with a bit of a twist}
14
14
  s.email = %q{jakob.vidmar@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -28,7 +28,9 @@ Gem::Specification.new do |s|
28
28
  "test/helper.rb",
29
29
  "test/models/category.rb",
30
30
  "test/models/ordered_category.rb",
31
+ "test/models/shapes.rb",
31
32
  "test/test_order.rb",
33
+ "test/test_search_class.rb",
32
34
  "test/test_tree.rb"
33
35
  ]
34
36
  s.homepage = %q{http://github.com/ramdiv/mongo_mapper_acts_as_tree}
@@ -40,7 +42,9 @@ Gem::Specification.new do |s|
40
42
  "test/helper.rb",
41
43
  "test/models/category.rb",
42
44
  "test/models/ordered_category.rb",
45
+ "test/models/shapes.rb",
43
46
  "test/test_order.rb",
47
+ "test/test_search_class.rb",
44
48
  "test/test_tree.rb"
45
49
  ]
46
50
 
data/test/helper.rb CHANGED
@@ -11,11 +11,9 @@ MongoMapper.database = "acts_as_tree-test"
11
11
  Dir["#{File.dirname(__FILE__)}/models/*.rb"].each {|file| require file}
12
12
 
13
13
  class Test::Unit::TestCase
14
- # Drop all columns after each test case.
15
- def teardown
16
- MongoMapper.database.collections.each do |coll|
17
- coll.remove
18
- end
14
+ # Drop all collections after each test case.
15
+ def teardown
16
+ MongoMapper.database.collections.each {|collection| collection.drop }
19
17
  end
20
18
 
21
19
  # Make sure that each test case has a teardown
@@ -0,0 +1,14 @@
1
+ require "mongo_mapper"
2
+ require "mongo_mapper_acts_as_tree"
3
+
4
+ class Shape
5
+ include MongoMapper::Document
6
+ include MongoMapper::Acts::Tree
7
+
8
+ key :name, String
9
+
10
+ acts_as_tree :search_class => Shape
11
+ end
12
+
13
+ class Circle < Shape; end
14
+ class Square < Shape; end
@@ -0,0 +1,90 @@
1
+ require 'helper'
2
+
3
+ class TestSearchScope < Test::Unit::TestCase
4
+ context "Simple, mixed type tree" do
5
+ setup do
6
+ shape = Shape.create(:name => "Root")
7
+ Circle.create(:name => "Circle", :parent => shape)
8
+ Square.create(:name => "Square", :parent => shape)
9
+ end
10
+
11
+ setup do
12
+ # We are loading from the database here because this process proves the point. If we never did it this
13
+ # way, there would be no reason to change the code.
14
+ @shape, @circle, @square = Shape.first, Circle.first, Square.first
15
+ end
16
+
17
+ should "return circle and square as children of shape" do
18
+ assert_equal [@circle, @square], @shape.children
19
+ end
20
+
21
+ should("return shape as parent of circle") { assert_equal @shape, @circle.parent }
22
+ should("return shape as parent of square") { assert_equal @shape, @square.parent }
23
+
24
+ should("return square as exclusive sibling of circle") { assert_equal [@square], @circle.siblings }
25
+ should "return self and square as inclusive siblings of circle" do
26
+ assert_equal [@circle, @square], @circle.self_and_siblings
27
+ end
28
+
29
+ should("return circle as exclusive sibling of square") { assert_equal [@circle], @square.siblings }
30
+ should "return self and circle as inclusive siblings of square" do
31
+ assert_equal [@circle, @square], @square.self_and_siblings
32
+ end
33
+
34
+ should "return circle and square as exclusive descendants of shape" do
35
+ assert_equal [@circle, @square], @shape.descendants
36
+ end
37
+ should "return shape, circle and square as inclusive descendants of shape" do
38
+ assert_equal [@shape, @circle, @square], @shape.self_and_descendants
39
+ end
40
+
41
+ should("return shape as exclusive ancestor of circle") { assert_equal [@shape], @circle.ancestors }
42
+ should "return self and shape as inclusive ancestors of circle" do
43
+ assert_equal [@shape, @circle], @circle.self_and_ancestors
44
+ end
45
+
46
+ should("return shape as exclusive ancestor of square") { assert_equal [@shape], @square.ancestors }
47
+ should "return self and shape as inclusive ancestors of square" do
48
+ assert_equal [@shape, @square], @square.self_and_ancestors
49
+ end
50
+
51
+ should("return shape as root of circle") { assert_equal @shape, @square.root }
52
+ should("return shape as root of square") { assert_equal @shape, @circle.root }
53
+ end
54
+
55
+ context "A tree with mixed types on either side of a branch" do
56
+ setup do
57
+ shape = Shape.create(:name => "Root")
58
+ circle = Circle.create(:name => "Circle", :parent => shape)
59
+ Square.create(:name => "Square", :parent => circle)
60
+ end
61
+
62
+ setup do
63
+ @shape, @circle, @square = Shape.first, Circle.first, Square.first
64
+ end
65
+
66
+ should("return circle as child of shape") { assert_equal [@circle], @shape.children }
67
+ should("return square as child of circle") { assert_equal [@square], @circle.children }
68
+ should("return circle as parent of square") { assert_equal @circle, @square.parent }
69
+ should("return shape as parent of circle") { assert_equal @shape, @circle.parent }
70
+
71
+ should "return circle and square as descendants of shape" do
72
+ assert_equal [@circle, @square], @shape.descendants
73
+ end
74
+
75
+ should("return square as descendant of circle") { assert_equal [@square], @circle.descendants }
76
+
77
+ should "return shape and circle as ancestors of square" do
78
+ assert_equal [@shape, @circle], @square.ancestors
79
+ end
80
+
81
+ should("return shape as ancestor of circle") { assert_equal [@shape], @circle.ancestors }
82
+
83
+ should "destroy descendants of shape" do
84
+ @shape.destroy_descendants
85
+ assert_nil Shape.find(@circle._id)
86
+ assert_nil Shape.find(@square._id)
87
+ end
88
+ end
89
+
90
+ end # TestSearchScope
data/test/test_tree.rb CHANGED
@@ -12,9 +12,9 @@ class TestMongomapperActsAsTree < Test::Unit::TestCase
12
12
  @root_2 = Category.create(:name => "Root 2")
13
13
  end
14
14
 
15
- should "create node from id " do
16
- assert Category.create(:name => "Child 2.2", :parent => @root_1.id.to_s).parent == @root_1
17
- end
15
+ should "create node from id " do
16
+ assert Category.create(:name => "Child 2.2", :parent => @root_1.id.to_s).parent == @root_1
17
+ end
18
18
 
19
19
  should "have roots" do
20
20
  assert eql_arrays?(Category.roots, [@root_1, @root_2])
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 5
9
- version: 0.0.5
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jakob Vidmar
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-27 00:00:00 +01:00
17
+ date: 2010-06-05 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -66,7 +66,9 @@ files:
66
66
  - test/helper.rb
67
67
  - test/models/category.rb
68
68
  - test/models/ordered_category.rb
69
+ - test/models/shapes.rb
69
70
  - test/test_order.rb
71
+ - test/test_search_class.rb
70
72
  - test/test_tree.rb
71
73
  has_rdoc: true
72
74
  homepage: http://github.com/ramdiv/mongo_mapper_acts_as_tree
@@ -102,5 +104,7 @@ test_files:
102
104
  - test/helper.rb
103
105
  - test/models/category.rb
104
106
  - test/models/ordered_category.rb
107
+ - test/models/shapes.rb
105
108
  - test/test_order.rb
109
+ - test/test_search_class.rb
106
110
  - test/test_tree.rb