mongoid-tree-rational 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
@@ -0,0 +1,12 @@
1
+ before_install:
2
+ - gem update --system
3
+ - gem --version
4
+ language: ruby
5
+ rvm:
6
+ - 2.0.0
7
+ - 1.9.3
8
+ - 2.0.0
9
+ - jruby-19mode
10
+ - rbx-19mode
11
+ services:
12
+ - mongodb
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'mongoid', ['<= 4.0', '>= 3.0']
4
+ gem 'rational_number'
5
+
6
+ group :development do
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem 'yard'
10
+ gem 'jeweler'
11
+ gem 'guard-rspec', '>= 2.6.0'
12
+ gem 'rb-inotify', :require => false
13
+ gem 'rb-fsevent', :require => false
14
+ gem 'wdm', :platforms => [:mswin, :mingw], :require => false
15
+ gem 'hirb'
16
+ gem 'wirble'
17
+ gem 'awesome_print'
18
+ end
19
+
20
+ group :development, :test do
21
+ gem 'coveralls', :require => false
22
+ gem 'simplecov', :require => false
23
+ end
@@ -0,0 +1,6 @@
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch(%r{^spec/support/.+\.rb$}) { "spec" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2010-2012 Benedikt Deicke
2
+ Copyright (c) 2013 Leif Ringstad (Rational numbering additions)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,287 @@
1
+ # mongoid-tree [![Build Status](https://secure.travis-ci.org/boxcms/mongoid-tree-rational.png?branch=master)](https://travis-ci.org/boxcms/mongoid-tree-rational) [![Dependency Status](https://gemnasium.com/boxcms/mongoid-tree-rational.png)](https://gemnasium.com/boxcms/mongoid-tree-rational) [![Coverage Status](https://coveralls.io/repos/boxcms/mongoid-tree-rational/badge.png)](https://coveralls.io/r/boxcms/mongoid-tree-rational)
2
+
3
+ A tree structure for Mongoid documents using rational numbers and materialized path pattern
4
+
5
+ ## Requirements
6
+
7
+ * mongoid (~> 3.0)
8
+
9
+ This version will only support mongoid 3.0+
10
+
11
+ ## Install
12
+
13
+ To install mongoid_tree_rational, simply add it to your Gemfile:
14
+
15
+ gem 'mongoid-tree-rational', :require => 'mongoid/tree'
16
+
17
+ In order to get the latest development version of mongoid-tree:
18
+
19
+ gem 'mongoid-tree-rational', :git => 'git://github.com/boxcms/mongoid-tree-rational', :require => 'mongoid/tree'
20
+
21
+ You might want to remove the `:require => 'mongoid/tree'` option and explicitly `require 'mongoid/tree'` where needed and finally run
22
+
23
+ bundle install
24
+
25
+
26
+ ## Usage
27
+
28
+ ```ruby
29
+ class Node
30
+ include Mongoid::Document
31
+ include Mongoid::Tree
32
+ include Mongoid::Tree::RationalNumbering
33
+ end
34
+ ```
35
+
36
+ ### Utility methods
37
+
38
+ There are several utility methods that help getting to other related documents in the tree:
39
+
40
+ ```ruby
41
+ Node.root
42
+ Node.roots
43
+ Node.leaves
44
+
45
+ node.root
46
+ node.parent
47
+ node.children
48
+ node.ancestors
49
+ node.ancestors_and_self
50
+ node.descendants
51
+ node.descendants_and_self
52
+ node.siblings
53
+ node.siblings_and_self
54
+ node.leaves
55
+ ```
56
+
57
+ In addition it's possible to check certain aspects of the document's position in the tree:
58
+
59
+ ```ruby
60
+ node.root?
61
+ node.leaf?
62
+ node.depth
63
+ node.ancestor_of?(other)
64
+ node.descendant_of?(other)
65
+ node.sibling_of?(other)
66
+ ```
67
+
68
+ See `Mongoid::Tree` for more information on these methods.
69
+
70
+
71
+ ### Ordering
72
+
73
+ `Mongoid::Tree` doesn't order children by default. To enable ordering of tree nodes include the `Mongoid::Tree::RationalNumbering` or the `Mongoid::Tree::Ordering` module.
74
+
75
+
76
+ #### By rational numbers
77
+
78
+ To use rational ordering, include the `Mongoid::Tree::RationalNumbering` module. This will add a `position` field to your document and provide additional utility methods:
79
+
80
+ While rational numbering requires more processing when saving, it does give the benefit of querying an entire tree in one go.
81
+
82
+
83
+ Mathematical details about rational numbers in nested trees can be found here: [http://arxiv.org/pdf/0806.3115v1.pdf](http://arxiv.org/pdf/0806.3115v1.pdf)
84
+
85
+
86
+ ```ruby
87
+ node.set_rational_number(nv,dv) # set the nv/dv directly if you have the values
88
+ # returns true/false + errors if any.
89
+ node.lower_siblings
90
+ node.higher_siblings
91
+ node.first_sibling_in_list
92
+ node.last_sibling_in_list
93
+ node.siblings_between(other_node)
94
+
95
+ node.tree # get the entire tree under the node (Triggers 1 query only! Hurray)
96
+ node.tree_and_self # # get the entire tree under the node including node
97
+
98
+ node.move_up
99
+ node.move_down
100
+ node.move_to_top
101
+ node.move_to_bottom
102
+ node.move_above(other)
103
+ node.move_below(other)
104
+
105
+ node.at_top?
106
+ node.at_bottom?
107
+ ```
108
+
109
+ Example:
110
+
111
+ ```ruby
112
+ class Node
113
+ include Mongoid::Document
114
+ include Mongoid::Tree
115
+ include Mongoid::Tree::RationalNumbering
116
+ end
117
+ ```
118
+
119
+ There are one additional class function
120
+ ```ruby
121
+ Node.rekey_all! # Will iterate over the entire tree and rekey every single node.
122
+ # Please note that this might take a while for a large tree.
123
+ # Do this in a background worker or rake task.
124
+ end
125
+ ```
126
+
127
+ You can get the entire tree in one go like this:
128
+
129
+ ```ruby
130
+ # - node_1
131
+ # - node_1_1
132
+ # - node_1_2
133
+ # - node_2
134
+ # - node_2_1
135
+ # - node_2_1_1
136
+ # - node_2_1_2
137
+ # - node_2_2
138
+ # - node_2_2_1
139
+ # - node_2_2_2
140
+
141
+ Node.all # Get the entire tree
142
+ # -> [node_1, node_1_1, node_1_2, node_2, node_2_1, node_2_1_1, node_2_1_2, node_2_2, node_2_2_1, node_2_2_2]
143
+ end
144
+ ```
145
+
146
+ See `Mongoid::Tree::RationalNumbering` for more information on these methods.
147
+
148
+ #### By 0-based integer (simple)
149
+
150
+ To use simple ordering, include the `Mongoid::Tree::Ordering` module. This will add a `position` field to your document and provide additional utility methods:
151
+
152
+ ```ruby
153
+ node.lower_siblings
154
+ node.higher_siblings
155
+ node.first_sibling_in_list
156
+ node.last_sibling_in_list
157
+
158
+ node.move_up
159
+ node.move_down
160
+ node.move_to_top
161
+ node.move_to_bottom
162
+ node.move_above(other)
163
+ node.move_below(other)
164
+
165
+ node.at_top?
166
+ node.at_bottom?
167
+ ```
168
+
169
+ Example:
170
+
171
+ ```ruby
172
+ class Node
173
+ include Mongoid::Document
174
+ include Mongoid::Tree
175
+ include Mongoid::Tree::Ordering
176
+ end
177
+ ```
178
+
179
+ See `Mongoid::Tree::Ordering` for more information on these methods.
180
+
181
+ ### Traversal
182
+
183
+ It's possible to traverse the tree using different traversal methods using the `Mongoid::Tree::Traversal` module.
184
+
185
+ Example:
186
+
187
+ ```ruby
188
+ class Node
189
+ include Mongoid::Document
190
+ include Mongoid::Tree
191
+ include Mongoid::Tree::Traversal
192
+ end
193
+
194
+ node.traverse(:breadth_first) do |n|
195
+ # Do something with Node n
196
+ end
197
+ ```
198
+
199
+ ### Destroying
200
+
201
+ `Mongoid::Tree` does not handle destroying of nodes by default. However it provides several strategies that help you to deal with children of deleted documents. You can simply add them as `before_destroy` callbacks.
202
+
203
+ Available strategies are:
204
+
205
+ * `:nullify_children` -- Sets the children's parent_id to null
206
+ * `:move_children_to_parent` -- Moves the children to the current document's parent
207
+ * `:destroy_children` -- Destroys all children by calling their `#destroy` method (invokes callbacks)
208
+ * `:delete_descendants` -- Deletes all descendants using a database query (doesn't invoke callbacks)
209
+
210
+ Example:
211
+
212
+ ```ruby
213
+ class Node
214
+ include Mongoid::Document
215
+ include Mongoid::Tree
216
+
217
+ before_destroy :nullify_children
218
+ end
219
+ ```
220
+
221
+
222
+ ### Callbacks
223
+
224
+ There are two callbacks that are called before and after the rearranging process. This enables you to do additional computations after the documents position in the tree is updated. See `Mongoid::Tree` for details.
225
+
226
+ Example:
227
+
228
+ ```ruby
229
+ class Page
230
+ include Mongoid::Document
231
+ include Mongoid::Tree
232
+
233
+ after_rearrange :rebuild_path
234
+
235
+ field :slug
236
+ field :path
237
+
238
+ private
239
+
240
+ def rebuild_path
241
+ self.path = self.ancestors_and_self.collect(&:slug).join('/')
242
+ end
243
+ end
244
+ ```
245
+
246
+ ### Validations
247
+
248
+ `Mongoid::Tree` currently does not validate the document's children or parent associations by default. To explicitly enable validation for children and parent documents it's required to add a `validates_associated` validation.
249
+
250
+ Example:
251
+
252
+ ```ruby
253
+ class Node
254
+ include Mongoid::Document
255
+ include Mongoid::Tree
256
+
257
+ validates_associated :parent, :children
258
+ end
259
+ ```
260
+
261
+ ## Build Status
262
+
263
+ mongoid-tree is on [Travis CI](http://travis-ci.org/boxcms/mongoid-tree-rational) running the specs on Ruby Head, Ruby 1.9.3, JRuby (1.9 mode), and Rubinius (1.9 mode).
264
+
265
+ ## Known issues
266
+
267
+ See [github.com/boxcms/mongoid-tree-rational/issues](https://github.com/boxcms/mongoid-tree-rational/issues)
268
+
269
+
270
+ ## Repository
271
+
272
+ See [github.com/boxcms/mongoid-tree-rational](https://github.com/boxcms/mongoid-tree-rational) and feel free to fork it!
273
+
274
+
275
+ ## MongoMapper version
276
+
277
+ Have a look here: [github.com/leifcr/mm-tree](https://github.com/leifcr/mm-tree)
278
+
279
+ ## Contributors
280
+
281
+ See a list of all contributors at [github.com/boxcms/mongoid-tree-rational/contributors](https://github.com/boxcms/mongoid-tree-rational/contributors). Thanks!
282
+
283
+ A huge thanks to [Benedikt Deicke](https://github.com/benedikt) for all the work on mongoid-tree. This rational number version is based on his work
284
+
285
+ ## Copyright
286
+
287
+ See LICENSE for details.
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
16
+
17
+ require 'jeweler'
18
+ Jeweler::Tasks.new do |gem|
19
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
20
+ gem.name = "mongoid-tree-rational"
21
+ gem.version = version
22
+ gem.homepage = "https://github.com/boxcms/mongoid-tree-rational"
23
+ gem.license = "MIT"
24
+ gem.summary = %Q{A tree structure for Mongoid documents with rational numbers}
25
+ gem.description = %Q{A tree structure for Mongoid documents using the materialized path pattern and rational number sorting.}
26
+ gem.email = "leifcr@gmail.com"
27
+ gem.authors = ['Leif Ringstad', 'Benedikt Deicke']
28
+ # dependencies defined in Gemfile
29
+ end
30
+ Jeweler::RubygemsDotOrgTasks.new
31
+
32
+ # RDoc::Task.new(:rdoc) do |rdoc|
33
+ # rdoc.rdoc_dir = 'rdoc'
34
+ # rdoc.title = "Mongoid Tree Rational #{version}"
35
+ # rdoc.options << '--line-numbers'
36
+ # rdoc.rdoc_files.include('README.rdoc')
37
+ # rdoc.rdoc_files.include('lib/**/*.rb')
38
+ # end
39
+
40
+ # Bundler::GemHelper.install_tasks
41
+
42
+ require 'rspec/core'
43
+ require 'rspec/core/rake_task'
44
+ RSpec::Core::RakeTask.new(:spec) do |spec|
45
+ spec.pattern = FileList['spec/**/*_spec.rb']
46
+ end
47
+
48
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
49
+ spec.pattern = 'spec/**/*_spec.rb'
50
+ spec.rcov = true
51
+ end
52
+
53
+ task :default => :spec
54
+
55
+ # YARD::Rake::YardocTask.new(:doc)
56
+
57
+ desc "Open an irb session"
58
+ task :test_console do
59
+ require 'wirble'
60
+ require 'ap'
61
+ require 'hirb'
62
+ sh "irb -rubygems -I lib -r ./spec/spec_helper.rb"
63
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,11 @@
1
+ en:
2
+ mongoid:
3
+ errors:
4
+ messages:
5
+ tree:
6
+ cyclic: "Can't be children of a descendant"
7
+ search_class_mismatch: "Mismatch between search classes. Parent: %{parent_search_class} Node: %{node_search_class}"
8
+ rational:
9
+ incorrect_parent: "Positional values doesn't match parent (check nv/dv values)"
10
+ parent_does_not_exist: "Parent does not exist. Cannot move to nv: %{nv} dv: %{dv}"
11
+ #cannot_set_parent: "Cannot set the parent"
@@ -0,0 +1,8 @@
1
+ nb:
2
+ mongoid:
3
+ errors:
4
+ messages:
5
+ tree:
6
+ cyclic: "Kan ikke være barnet av en etterkommer."
7
+ incorrect_parent_nv_dv: "Posisjonelle/rasjonelle verdier stemmer ikke (check nv/dv values)"
8
+ search_class_mismatch: "Søke klassene er ikke identiske. Forelder: %{parent_search_class} Node/barn: %{node_search_class}."