ramdiv-mongo_mapper_acts_as_tree 0.0.5 → 0.1.0

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