mongoid-tree-rational 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/.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}."