mongo_mapper_tree 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Joel Junström, Oktavilla
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,44 @@
1
+ = mongo_mapper_tree
2
+
3
+ This is an modernized version of mongo_mapper_acts_as_tree (https://github.com/ramdiv/mongo_mapper_acts_as_tree)
4
+ In it's essence it's an implementation of a tree structure for MongoMapper, think acts as tree but for mongodb.
5
+
6
+
7
+ == Installation
8
+
9
+ Install as gem
10
+
11
+ gem install mongo_mapper_tree
12
+
13
+ == Usage
14
+
15
+ Enable the tree functionality by declaring acts_as_tree on your model
16
+
17
+ class Category
18
+ include MongoMapper::Document
19
+ plugin MongoMapper::Plugins::Tree
20
+
21
+ key :name, String
22
+ end
23
+
24
+ This adds class_attributes called parent_id_field, path_field, depth_field, tree_order and tree_search_class.
25
+
26
+ parent_id_field, path_field and depth_field overrides the default field names
27
+ tree_order controls the order (format :field_name.[asc|desc])
28
+ tree_search_class expects a Class that is a MongoMapper::Document to be used for search
29
+
30
+ Check test_tree.rb and test_search_class.rb for examples.
31
+
32
+ == Note on Patches/Pull Requests
33
+
34
+ * Fork the project.
35
+ * Make your feature addition or bug fix.
36
+ * Add tests for it. This is important so I don't break it in a
37
+ future version unintentionally.
38
+ * Commit, do not mess with rakefile, version, or history.
39
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
40
+ * Send me a pull request. Bonus points for topic branches.
41
+
42
+ == Copyright
43
+
44
+ Copyright (c) 2011 Joel Junström. See LICENSE for details.
data/lib/locale/en.yml ADDED
@@ -0,0 +1,5 @@
1
+ en:
2
+ mongo_mapper:
3
+ errors:
4
+ messages:
5
+ cyclic: "Can't be children of a descendant"
@@ -0,0 +1,160 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Tree
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ def roots
9
+ self.where(parent_id_field => nil).sort(tree_order).all
10
+ end
11
+ end
12
+
13
+ module InstanceMethods
14
+ def tree_search_class
15
+ self.class.tree_search_class
16
+ end
17
+
18
+ def will_save_tree
19
+ if parent && self.descendants.include?(parent)
20
+ errors.add(:base, :cyclic)
21
+ end
22
+ end
23
+
24
+ def fix_position(opts = {})
25
+ if parent.nil?
26
+ self[parent_id_field] = nil
27
+ self[path_field] = []
28
+ self[depth_field] = 0
29
+ elsif !!opts[:force] || self.changes.include?(parent_id_field)
30
+ @_will_move = true
31
+ self[path_field] = parent[path_field] + [parent._id]
32
+ self[depth_field] = parent[depth_field] + 1
33
+ end
34
+ end
35
+
36
+ def fix_position!
37
+ fix_position(:force => true)
38
+ save
39
+ end
40
+
41
+ def root?
42
+ self[parent_id_field].nil?
43
+ end
44
+
45
+ def root
46
+ self[path_field].first.nil? ? self : tree_search_class.find(self[path_field].first)
47
+ end
48
+
49
+ def ancestors
50
+ return [] if root?
51
+ tree_search_class.find(self[path_field])
52
+ end
53
+
54
+ def self_and_ancestors
55
+ ancestors << self
56
+ end
57
+
58
+ def siblings
59
+ tree_search_class.where({
60
+ :_id => { "$ne" => self._id },
61
+ parent_id_field => self[parent_id_field]
62
+ }).sort(tree_order).all
63
+ end
64
+
65
+ def self_and_siblings
66
+ tree_search_class.where({
67
+ parent_id_field => self[parent_id_field]
68
+ }).sort(tree_order).all
69
+ end
70
+
71
+ def children
72
+ tree_search_class.where(parent_id_field => self._id).sort(tree_order).all
73
+ end
74
+
75
+ def descendants
76
+ return [] if new_record?
77
+ tree_search_class.where(path_field => self._id).sort(tree_order).all
78
+ end
79
+
80
+ def self_and_descendants
81
+ [self] + self.descendants
82
+ end
83
+
84
+ def is_ancestor_of?(other)
85
+ other[path_field].include?(self._id)
86
+ end
87
+
88
+ def is_or_is_ancestor_of?(other)
89
+ (other == self) or is_ancestor_of?(other)
90
+ end
91
+
92
+ def is_descendant_of?(other)
93
+ self[path_field].include?(other._id)
94
+ end
95
+
96
+ def is_or_is_descendant_of?(other)
97
+ (other == self) or is_descendant_of?(other)
98
+ end
99
+
100
+ def is_sibling_of?(other)
101
+ (other != self) and (other[parent_id_field] == self[parent_id_field])
102
+ end
103
+
104
+ def is_or_is_sibling_of?(other)
105
+ (other == self) or is_sibling_of?(other)
106
+ end
107
+
108
+ def move_children
109
+ if @_will_move
110
+ @_will_move = false
111
+ self.children.each do |child|
112
+ child.fix_position!
113
+ end
114
+ @_will_move = true
115
+ end
116
+ end
117
+
118
+ def destroy_descendants
119
+ tree_search_class.destroy(self.descendants.map(&:_id))
120
+ end
121
+ end
122
+
123
+ included do
124
+ # Tree search class will be used as the base from which to
125
+ # find tree objects. This is handy should you have a tree of objects that are of different types, but
126
+ # might be related through single table inheritance.
127
+ #
128
+ # self.tree_search_class = Shape
129
+ #
130
+ # In the above example, you could have a working tree ofShape, Circle and Square types (assuming
131
+ # Circle and Square were subclasses of Shape). If you want to do the same thing and you don't provide
132
+ # tree_search_class, nesting mixed types will not work.
133
+ class_attribute :tree_search_class
134
+ self.tree_search_class ||= self
135
+
136
+ class_attribute :parent_id_field
137
+ self.parent_id_field ||= "parent_id"
138
+
139
+ class_attribute :path_field
140
+ self.path_field ||= "path"
141
+
142
+ class_attribute :depth_field
143
+ self.depth_field ||= "depth"
144
+
145
+ class_attribute :tree_order
146
+
147
+ key parent_id_field, ObjectId
148
+ key path_field, Array, :default => [], :index => true
149
+ key depth_field, Integer, :default => 0
150
+
151
+ belongs_to :parent, :class => tree_search_class
152
+
153
+ validate :will_save_tree
154
+ after_validation :fix_position
155
+ after_save :move_children
156
+ before_destroy :destroy_descendants
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: UTF-8
2
+ require 'mongo_mapper'
3
+ I18n.load_path << File.expand_path('../locale/en.yml', __FILE__)
4
+ require 'mongo_mapper/plugins/tree'
data/lib/version.rb ADDED
@@ -0,0 +1,4 @@
1
+ # encoding: UTF-8
2
+ module MongoMapperTree
3
+ Version = '0.0.1'
4
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'database_cleaner'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require 'mongo_mapper_tree'
9
+
10
+ MongoMapper.database = "mongo_mapper_tree-test"
11
+
12
+ Dir["#{File.dirname(__FILE__)}/models/*.rb"].each {|file| require file}
13
+
14
+ DatabaseCleaner.strategy = :truncation
15
+
16
+ class Test::Unit::TestCase
17
+ # Drop all collections after each test case.
18
+ def setup
19
+ DatabaseCleaner.start
20
+ end
21
+
22
+ def teardown
23
+ DatabaseCleaner.clean
24
+ end
25
+
26
+ # Make sure that each test case has a teardown
27
+ # method to clear the db after each test.
28
+ def inherited(base)
29
+ base.define_method setup do
30
+ super
31
+ end
32
+
33
+ base.define_method teardown do
34
+ super
35
+ end
36
+ end
37
+
38
+ def eql_arrays?(first, second)
39
+ first.collect(&:_id).to_set == second.collect(&:_id).to_set
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ class Category
2
+ include MongoMapper::Document
3
+ plugin MongoMapper::Plugins::Tree
4
+
5
+ key :name, String
6
+ end
@@ -0,0 +1,9 @@
1
+ class OrderedCategory
2
+ include MongoMapper::Document
3
+ plugin MongoMapper::Plugins::Tree
4
+
5
+ key :name, String
6
+ key :value, Integer
7
+
8
+ self.tree_order = :value.asc
9
+ end
@@ -0,0 +1,10 @@
1
+ class Shape
2
+ include MongoMapper::Document
3
+ plugin MongoMapper::Plugins::Tree
4
+ self.tree_search_class = Shape
5
+
6
+ key :name, String
7
+ end
8
+
9
+ class Circle < Shape; end
10
+ class Square < Shape; end
@@ -0,0 +1,26 @@
1
+ require 'helper'
2
+ class TestMongomapperActsAsTree < Test::Unit::TestCase
3
+ context "Ordered tree" do
4
+ setup do
5
+ @root_1 = OrderedCategory.create(:name => "Root 1", :value => 2)
6
+ @child_1 = OrderedCategory.create(:name => "Child 1", :parent => @root_1, :value => 1)
7
+ @child_2 = OrderedCategory.create(:name => "Child 2", :parent => @root_1, :value => 9)
8
+ @child_2_1 = OrderedCategory.create(:name => "Child 2.1", :parent => @child_2, :value => 2)
9
+ @child_3 = OrderedCategory.create(:name => "Child 3", :parent => @root_1, :value => 5)
10
+ @root_2 = OrderedCategory.create(:name => "Root 2", :value => 1)
11
+ end
12
+
13
+ should "be in order" do
14
+ assert_equal OrderedCategory.roots, [@root_2, @root_1]
15
+
16
+ assert_equal @root_1.children, [@child_1, @child_3, @child_2]
17
+
18
+ assert_equal @root_1.descendants, [@child_1, @child_2_1, @child_3, @child_2]
19
+ assert_equal @root_1.self_and_descendants, [@root_1, @child_1, @child_2_1, @child_3, @child_2]
20
+
21
+ assert_equal @child_2.siblings, [@child_1, @child_3]
22
+ assert_equal @child_2.self_and_siblings, [@child_1, @child_3, @child_2]
23
+ assert_equal @root_1.self_and_siblings, [@root_2, @root_1]
24
+ end
25
+ end
26
+ 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 ADDED
@@ -0,0 +1,157 @@
1
+ require 'helper'
2
+ class TestMongomapperActsAsTree < Test::Unit::TestCase
3
+ context "Tree" do
4
+ setup do
5
+ @root_1 = Category.create(:name => "Root 1")
6
+ @child_1 = Category.create(:name => "Child 1", :parent => @root_1)
7
+ @child_2 = Category.create(:name => "Child 2", :parent => @root_1)
8
+ @child_2_1 = Category.create(:name => "Child 2.1", :parent => @child_2)
9
+ @child_3 = Category.create(:name => "Child 3", :parent => @root_1)
10
+ @root_2 = Category.create(:name => "Root 2")
11
+ end
12
+
13
+ should "create node from id " do
14
+ assert Category.create(:name => "Child 2.2", :parent_id => @root_1.id).parent == @root_1
15
+ end
16
+
17
+ should "have roots" do
18
+ assert eql_arrays?(Category.roots, [@root_1, @root_2])
19
+ end
20
+
21
+ context "node" do
22
+ should "have a root" do
23
+ assert_equal @root_1.root, @root_1
24
+ assert_not_equal @root_1.root, @root_2.root
25
+ assert_equal @root_1, @child_2_1.root
26
+ end
27
+
28
+ should "have ancestors" do
29
+ assert_equal @root_1.ancestors, []
30
+ assert_equal @child_2_1.ancestors, [@root_1, @child_2]
31
+ assert_equal @root_1.self_and_ancestors, [@root_1]
32
+ assert_equal @child_2_1.self_and_ancestors, [@root_1, @child_2, @child_2_1]
33
+ end
34
+
35
+ should "have siblings" do
36
+ assert eql_arrays?(@root_1.siblings, [@root_2])
37
+ assert eql_arrays?(@child_2.siblings, [@child_1, @child_3])
38
+ assert eql_arrays?(@child_2_1.siblings, [])
39
+ assert eql_arrays?(@root_1.self_and_siblings, [@root_1, @root_2])
40
+ assert eql_arrays?(@child_2.self_and_siblings, [@child_1, @child_2, @child_3])
41
+ assert eql_arrays?(@child_2_1.self_and_siblings, [@child_2_1])
42
+ end
43
+
44
+ should "set depth" do
45
+ assert_equal 0, @root_1.depth
46
+ assert_equal 1, @child_1.depth
47
+ assert_equal 2, @child_2_1.depth
48
+ end
49
+
50
+ should "have children" do
51
+ assert @child_2_1.children.empty?
52
+ assert eql_arrays?(@root_1.children, [@child_1, @child_2, @child_3])
53
+ end
54
+
55
+ should "have descendants" do
56
+ assert eql_arrays?(@root_1.descendants, [@child_1, @child_2, @child_3, @child_2_1])
57
+ assert eql_arrays?(@child_2.descendants, [@child_2_1])
58
+ assert @child_2_1.descendants.empty?
59
+ assert eql_arrays?(@root_1.self_and_descendants, [@root_1, @child_1, @child_2, @child_3, @child_2_1])
60
+ assert eql_arrays?(@child_2.self_and_descendants, [@child_2, @child_2_1])
61
+ assert eql_arrays?(@child_2_1.self_and_descendants, [@child_2_1])
62
+ end
63
+
64
+ should "be able to tell if ancestor" do
65
+ assert @root_1.is_ancestor_of?(@child_1)
66
+ assert ! @root_2.is_ancestor_of?(@child_2_1)
67
+ assert ! @child_2.is_ancestor_of?(@child_2)
68
+
69
+ assert @root_1.is_or_is_ancestor_of?(@child_1)
70
+ assert ! @root_2.is_or_is_ancestor_of?(@child_2_1)
71
+ assert @child_2.is_or_is_ancestor_of?(@child_2)
72
+ end
73
+
74
+ should "be able to tell if descendant" do
75
+ assert ! @root_1.is_descendant_of?(@child_1)
76
+ assert @child_1.is_descendant_of?(@root_1)
77
+ assert ! @child_2.is_descendant_of?(@child_2)
78
+
79
+ assert ! @root_1.is_or_is_descendant_of?(@child_1)
80
+ assert @child_1.is_or_is_descendant_of?(@root_1)
81
+ assert @child_2.is_or_is_descendant_of?(@child_2)
82
+ end
83
+
84
+ should "be able to tell if sibling" do
85
+ assert ! @root_1.is_sibling_of?(@child_1)
86
+ assert ! @child_1.is_sibling_of?(@child_1)
87
+ assert ! @child_2.is_sibling_of?(@child_2)
88
+
89
+ assert ! @root_1.is_or_is_sibling_of?(@child_1)
90
+ assert @child_1.is_or_is_sibling_of?(@child_2)
91
+ assert @child_2.is_or_is_sibling_of?(@child_2)
92
+ end
93
+
94
+ context "when moving" do
95
+ should "recalculate path and depth" do
96
+ @child_3.parent = @child_2
97
+ @child_3.save
98
+
99
+ assert @child_2.is_or_is_ancestor_of?(@child_3)
100
+ assert @child_3.is_or_is_descendant_of?(@child_2)
101
+ assert @child_2.children.include?(@child_3)
102
+ assert @child_2.descendants.include?(@child_3)
103
+ assert @child_2_1.is_or_is_sibling_of?(@child_3)
104
+ assert_equal 2, @child_3.depth
105
+ end
106
+
107
+ should "move children on save" do
108
+ @child_2.parent = @root_2
109
+
110
+ assert ! @root_2.is_or_is_ancestor_of?(@child_2_1)
111
+ assert ! @child_2_1.is_or_is_descendant_of?(@root_2)
112
+ assert ! @root_2.descendants.include?(@child_2_1)
113
+
114
+ @child_2.save
115
+ @child_2_1.reload
116
+
117
+ assert @root_2.is_or_is_ancestor_of?(@child_2_1)
118
+ assert @child_2_1.is_or_is_descendant_of?(@root_2)
119
+ assert @root_2.descendants.include?(@child_2_1)
120
+ end
121
+
122
+ should "check against cyclic graph" do
123
+ @root_1.parent = @child_2_1
124
+ assert ! @root_1.valid?
125
+ assert_equal I18n.t(:'mongo_mapper.errors.messages.cyclic'), @root_1.errors[:base].first
126
+ end
127
+
128
+ should "be able to become root" do
129
+ @child_2.parent = nil
130
+ @child_2.save
131
+ @child_2.reload
132
+ assert_nil @child_2.parent
133
+ @child_2_1.reload
134
+ assert (@child_2_1.path == [@child_2.id])
135
+ end
136
+
137
+ end
138
+
139
+ should "destroy descendants when destroyed" do
140
+ @child_2.destroy
141
+ assert_nil Category.find(@child_2_1._id)
142
+ end
143
+ end
144
+
145
+ context "root node" do
146
+ should "not have a parent" do
147
+ assert_nil @root_1.parent
148
+ end
149
+ end
150
+
151
+ context "child_node" do
152
+ should "have a parent" do
153
+ assert_equal @child_2, @child_2_1.parent
154
+ end
155
+ end
156
+ end
157
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongo_mapper_tree
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - "Joel Junstr\xC3\xB6m"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-08-05 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: mongo_mapper
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 0.9.1
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: shoulda
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: "2.10"
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ description: An Acts As Tree like implementation for MongoMapper based on mongo_mapper_acts_as_tree
39
+ email:
40
+ - joel.junstrom@oktavilla.se
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files: []
46
+
47
+ files:
48
+ - lib/locale/en.yml
49
+ - lib/mongo_mapper/plugins/tree.rb
50
+ - lib/mongo_mapper_tree.rb
51
+ - lib/version.rb
52
+ - test/helper.rb
53
+ - test/models/category.rb
54
+ - test/models/ordered_category.rb
55
+ - test/models/shapes.rb
56
+ - test/test_order.rb
57
+ - test/test_search_class.rb
58
+ - test/test_tree.rb
59
+ - LICENSE
60
+ - README.rdoc
61
+ has_rdoc: true
62
+ homepage: http://github.com/Oktavilla/mongo_mapper_tree
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options: []
67
+
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: -4220793794743588163
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: -4220793794743588163
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ requirements: []
89
+
90
+ rubyforge_project:
91
+ rubygems_version: 1.6.2
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: An Acts As Tree like implementation for MongoMapper
95
+ test_files:
96
+ - test/helper.rb
97
+ - test/models/category.rb
98
+ - test/models/ordered_category.rb
99
+ - test/models/shapes.rb
100
+ - test/test_order.rb
101
+ - test/test_search_class.rb
102
+ - test/test_tree.rb