mongoid-ancestry 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +21 -25
- data/VERSION +1 -1
- data/lib/mongoid/ancestry/class_methods.rb +14 -35
- data/lib/mongoid/ancestry/instance_methods.rb +38 -41
- data/mongoid-ancestry.gemspec +20 -2
- data/spec/mongoid/ancestry/class_methods_spec.rb +11 -16
- data/spec/mongoid/ancestry/instance_methods_spec.rb +29 -54
- data/spec/mongoid/ancestry_spec.rb +0 -7
- data/spec/support/models.rb +0 -1
- metadata +110 -44
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,40 +3,37 @@ Mongoid-ancestry
|
|
3
3
|
|
4
4
|
Mongoid-ancestry is a gem/plugin that allows the records of a Ruby on Rails Mongoid model to be organised as a tree structure (or hierarchy). It uses a single, intuitively formatted database column, using a variation on the materialised path pattern. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single query. Additional features are STI support, scopes, depth caching, depth constraints, easy migration from older plugins/gems, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records.
|
5
5
|
|
6
|
-
Installation
|
7
|
-
------------
|
6
|
+
## Installation
|
8
7
|
|
9
|
-
|
8
|
+
### It's Rails 3 only.
|
10
9
|
|
11
10
|
To apply Mongoid-ancestry to any Mongoid model, follow these simple steps:
|
12
11
|
|
13
12
|
1. Install
|
14
|
-
|
15
|
-
|
13
|
+
|
14
|
+
* Add to Gemfile: `gem 'ancestry'`
|
15
|
+
* Install required gems: `bundle install`
|
16
16
|
|
17
17
|
2. Add ancestry to your model
|
18
|
-
Add to app/models/[model].rb:
|
19
18
|
|
20
|
-
|
21
|
-
|
19
|
+
include Mongoid::Ancestry
|
20
|
+
has_ancestry
|
22
21
|
|
23
22
|
Your model is now a tree!
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
virtual model attributes, parent and parent_id can be set using parent= and parent_id= on a record or by including them
|
31
|
-
in the hash passed to new, create, create!, update_attributes and update_attributes!. For example:
|
24
|
+
## Organising records into a tree
|
25
|
+
You can use the parent attribute to organise your records into a tree. If you have the id of the record you want
|
26
|
+
to use as a parent and don't want to fetch it, you can also use parent_id. Like any virtual model attributes,
|
27
|
+
parent and parent_id can be set using parent= and parent_id= on a record or by including them in the hash passed
|
28
|
+
to new, create, create!, update_attributes and update_attributes!. For example:
|
32
29
|
|
33
30
|
TreeNode.create :name => 'Stinky', :parent => TreeNode.create(:name => 'Squeeky')
|
34
31
|
|
35
32
|
or
|
36
33
|
|
37
|
-
TreeNode.create :name => 'Stinky', :parent_id => TreeNode.create(:name => 'Squeeky').
|
34
|
+
TreeNode.create :name => 'Stinky', :parent_id => TreeNode.create(:name => 'Squeeky').id
|
38
35
|
|
39
|
-
|
36
|
+
#### Note: It doesn't work with `.create!` at the moment(mongoid bug? needs more investigation). But it absolutely will be fixed.
|
40
37
|
|
41
38
|
|
42
39
|
You can also create children through the children relation on a node:
|
@@ -75,7 +72,6 @@ To navigate an Ancestry model, use the following methods on any instance / recor
|
|
75
72
|
The has_ancestry methods supports the following options:
|
76
73
|
|
77
74
|
:ancestry_field Pass in a symbol to store ancestry in a different field
|
78
|
-
:uid_field Pass in a symbol to store unique id in a different field
|
79
75
|
:orphan_strategy Instruct Ancestry what to do with children of a node that is destroyed:
|
80
76
|
:destroy All children are destroyed as well (default)
|
81
77
|
:rootify The children of the destroyed node become root nodes
|
@@ -85,7 +81,7 @@ The has_ancestry methods supports the following options:
|
|
85
81
|
- Build cache: TreeNode.rebuild_depth_cache!
|
86
82
|
:depth_cache_field Pass in a symbol to store depth cache in a different field
|
87
83
|
|
88
|
-
##
|
84
|
+
## Scopes
|
89
85
|
|
90
86
|
Where possible, the navigation methods return scopes instead of records, this means additional ordering, conditions, limits, etc. can be applied and that the result can be either retrieved, counted or checked for existence. For example:
|
91
87
|
|
@@ -164,13 +160,13 @@ The arrange method takes Mongoid find options. If you want your hashes to be ord
|
|
164
160
|
With Mongoid-ancestry its easy to migrate from any of these plugins, to do so, use the build_ancestry_from_parent_ids! method on your model. These steps provide a more detailed explanation:
|
165
161
|
|
166
162
|
1. Remove old tree plugin or gem and add in Mongoid-ancestry
|
167
|
-
See 'Installation' for more info on installing and configuring gem
|
168
|
-
Add to app/models/[model].rb:
|
163
|
+
* See 'Installation' for more info on installing and configuring gem
|
164
|
+
* Add to app/models/[model].rb:
|
169
165
|
|
170
|
-
|
171
|
-
|
166
|
+
include Mongoid::Ancestry
|
167
|
+
has_ancestry
|
172
168
|
|
173
|
-
Create indexes
|
169
|
+
* Create indexes
|
174
170
|
|
175
171
|
2. Change your code
|
176
172
|
Most tree calls will probably work fine with ancestry
|
@@ -220,6 +216,6 @@ It's a fork of [original ancestry](https://github.com/stefankroes/ancestry) gem
|
|
220
216
|
|
221
217
|
All thanks should goes to Stefan Kroes for his great work.
|
222
218
|
|
223
|
-
Bug report? Faulty/incomplete documentation? Feature request? Please post an issue on
|
219
|
+
Bug report? Faulty/incomplete documentation? Feature request? Please post an issue on [issues tracker](http://github.com/skyeagle/mongoid-ancestry/issues).
|
224
220
|
|
225
221
|
Copyright (c) 2009 Stefan Kroes, released under the MIT license
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -3,14 +3,13 @@ module Mongoid
|
|
3
3
|
module ClassMethods
|
4
4
|
def has_ancestry(opts = {})
|
5
5
|
defaults = {
|
6
|
-
:uid_field => :uid,
|
7
6
|
:ancestry_field => :ancestry,
|
8
7
|
:cache_depth => false,
|
9
8
|
:depth_cache_field => :ancestry_depth,
|
10
9
|
:orphan_strategy => :destroy
|
11
10
|
}
|
12
11
|
|
13
|
-
valid_opts = [:
|
12
|
+
valid_opts = [:ancestry_field, :cache_depth, :depth_cache_field, :orphan_strategy]
|
14
13
|
unless opts.is_a?(Hash) && opts.keys.all? {|opt| valid_opts.include?(opt) }
|
15
14
|
raise Error.new("Invalid options for has_ancestry. Only hash is allowed.\n Defaults: #{defaults.inspect}")
|
16
15
|
end
|
@@ -19,13 +18,6 @@ module Mongoid
|
|
19
18
|
|
20
19
|
opts.reverse_merge!(defaults)
|
21
20
|
|
22
|
-
cattr_accessor :uid_field
|
23
|
-
self.uid_field = opts[:uid_field]
|
24
|
-
|
25
|
-
# Create unique id field accessor and set to option or default
|
26
|
-
self.field uid_field, :type => Integer
|
27
|
-
self.index uid_field, :unique => true
|
28
|
-
|
29
21
|
# Create ancestry field accessor and set to option or default
|
30
22
|
cattr_accessor :ancestry_field
|
31
23
|
self.ancestry_field = opts[:ancestry_field]
|
@@ -38,7 +30,7 @@ module Mongoid
|
|
38
30
|
self.orphan_strategy = opts[:orphan_strategy]
|
39
31
|
|
40
32
|
# Validate format of ancestry column value
|
41
|
-
primary_key_format = opts[:primary_key_format] || /[
|
33
|
+
primary_key_format = opts[:primary_key_format] || /[a-z0-9]+/
|
42
34
|
validates_format_of ancestry_field, :with => /\A#{primary_key_format.source}(\/#{primary_key_format.source})*\Z/, :allow_nil => true
|
43
35
|
|
44
36
|
# Validate that the ancestor ids don't include own id
|
@@ -74,8 +66,6 @@ module Mongoid
|
|
74
66
|
scope :ordered_by_ancestry, asc(:"#{self.base_class.ancestry_field}")
|
75
67
|
scope :ordered_by_ancestry_and, lambda {|by| ordered_by_ancestry.order_by([by]) }
|
76
68
|
|
77
|
-
before_create :set_uid
|
78
|
-
|
79
69
|
# Update descendants with new ancestry before save
|
80
70
|
before_save :update_descendants_with_new_ancestry
|
81
71
|
|
@@ -83,10 +73,6 @@ module Mongoid
|
|
83
73
|
before_destroy :apply_orphan_strategy
|
84
74
|
end
|
85
75
|
|
86
|
-
def find_by_uid!(uid)
|
87
|
-
where(self.base_class.uid_field => uid).first || raise(Mongoid::Errors::DocumentNotFound.new(self, uid))
|
88
|
-
end
|
89
|
-
|
90
76
|
# Fetch tree node if necessary
|
91
77
|
def to_node object
|
92
78
|
object.is_a?(self.base_class) ? object : find(object)
|
@@ -128,7 +114,7 @@ module Mongoid
|
|
128
114
|
node.ancestor_ids.inject(arranged_nodes) do |insertion_point, ancestor_id|
|
129
115
|
insertion_point.each do |parent, children|
|
130
116
|
# Change the insertion point to children if node is a descendant of this parent
|
131
|
-
insertion_point = children if ancestor_id == parent.
|
117
|
+
insertion_point = children if ancestor_id == parent.id
|
132
118
|
end; insertion_point
|
133
119
|
end[node] = ActiveSupport::OrderedHash.new; arranged_nodes
|
134
120
|
end
|
@@ -143,19 +129,19 @@ module Mongoid
|
|
143
129
|
begin
|
144
130
|
# ... check validity of ancestry column
|
145
131
|
if !node.valid? and !node.errors[node.class.ancestry_field].blank?
|
146
|
-
raise IntegrityError.new "Invalid format for ancestry column of node #{node.
|
132
|
+
raise IntegrityError.new "Invalid format for ancestry column of node #{node.id}: #{node.read_attribute node.ancestry_field}."
|
147
133
|
end
|
148
134
|
# ... check that all ancestors exist
|
149
135
|
node.ancestor_ids.each do |ancestor_id|
|
150
|
-
unless where(:
|
151
|
-
raise IntegrityError.new "Reference to non-existent node in node #{node.
|
136
|
+
unless where(:_id => ancestor_id).first
|
137
|
+
raise IntegrityError.new "Reference to non-existent node in node #{node.id}: #{ancestor_id}."
|
152
138
|
end
|
153
139
|
end
|
154
140
|
# ... check that all node parents are consistent with values observed earlier
|
155
141
|
node.path_ids.zip([nil] + node.path_ids).each do |node_id, parent_id|
|
156
142
|
parents[node_id] = parent_id unless parents.has_key? node_id
|
157
143
|
unless parents[node_id] == parent_id
|
158
|
-
raise IntegrityError.new "Conflicting parent id found in node #{node.
|
144
|
+
raise IntegrityError.new "Conflicting parent id found in node #{node.id}: #{parent_id || 'nil'} for node #{node_id} while expecting #{parents[node_id] || 'nil'}"
|
159
145
|
end
|
160
146
|
end
|
161
147
|
rescue IntegrityError => integrity_exception
|
@@ -181,19 +167,19 @@ module Mongoid
|
|
181
167
|
end
|
182
168
|
end
|
183
169
|
# ... save parent of this node in parents array if it exists
|
184
|
-
parents[node.
|
170
|
+
parents[node.id] = node.parent_id if exists? node.parent_id
|
185
171
|
|
186
172
|
# Reset parent id in array to nil if it introduces a cycle
|
187
|
-
parent = parents[node.
|
188
|
-
until parent.nil? || parent == node.
|
173
|
+
parent = parents[node.id]
|
174
|
+
until parent.nil? || parent == node.id
|
189
175
|
parent = parents[parent]
|
190
176
|
end
|
191
|
-
parents[node.
|
177
|
+
parents[node.id] = nil if parent == node.id
|
192
178
|
end
|
193
179
|
# For each node ...
|
194
180
|
self.base_class.all.each do |node|
|
195
181
|
# ... rebuild ancestry from parents array
|
196
|
-
ancestry, parent = nil, parents[node.
|
182
|
+
ancestry, parent = nil, parents[node.id]
|
197
183
|
until parent.nil?
|
198
184
|
ancestry, parent = if ancestry.nil? then parent else "#{parent}/#{ancestry}" end, parents[parent]
|
199
185
|
end
|
@@ -207,17 +193,10 @@ module Mongoid
|
|
207
193
|
def build_ancestry_from_parent_ids! parent_id = nil, ancestry = nil
|
208
194
|
self.base_class.where(:parent_id => parent_id).all.each do |node|
|
209
195
|
node.without_ancestry_callbacks do
|
210
|
-
|
211
|
-
begin
|
212
|
-
node.set_uid
|
213
|
-
node.send(:"#{ancestry_field}=", ancestry)
|
214
|
-
node.save!
|
215
|
-
rescue Mongo::OperationFailure => e
|
216
|
-
(retries -= 1) > 0 && e.to_s =~ %r{duplicate key error.+\$#{self.base_class.uid_field}} ? retry : raise(e)
|
217
|
-
end
|
196
|
+
node.update_attribute(self.base_class.ancestry_field, ancestry)
|
218
197
|
end
|
219
198
|
build_ancestry_from_parent_ids! node.id,
|
220
|
-
if ancestry.nil? then
|
199
|
+
if ancestry.nil? then node.id.to_s else "#{ancestry}/#{node.id}" end
|
221
200
|
end
|
222
201
|
end
|
223
202
|
|
@@ -1,26 +1,9 @@
|
|
1
1
|
module Mongoid
|
2
2
|
module Ancestry
|
3
3
|
module InstanceMethods
|
4
|
-
def save!(opts = {})
|
5
|
-
opts.merge!(:safe => true)
|
6
|
-
retries = 3
|
7
|
-
begin
|
8
|
-
super(opts)
|
9
|
-
rescue Mongo::OperationFailure => e
|
10
|
-
(retries -= 1) > 0 && e.to_s =~ %r{duplicate key error.+\$#{self.base_class.uid_field}} ? retry : raise(e)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
alias_method :save, :save!
|
14
|
-
|
15
|
-
def set_uid
|
16
|
-
previous = self.class.desc(:"#{self.base_class.uid_field}").first
|
17
|
-
uniq_id = previous ? previous.read_attribute(:"#{uid_field}").to_i + 1 : 1
|
18
|
-
send :"#{uid_field}=", uniq_id
|
19
|
-
end
|
20
|
-
|
21
4
|
# Validate that the ancestors don't include itself
|
22
5
|
def ancestry_exclude_self
|
23
|
-
if ancestor_ids.include?
|
6
|
+
if ancestor_ids.include? id
|
24
7
|
errors.add(:base, "#{self.class.name.humanize} cannot be a descendant of itself.")
|
25
8
|
end
|
26
9
|
end
|
@@ -37,9 +20,9 @@ module Mongoid
|
|
37
20
|
descendant.without_ancestry_callbacks do
|
38
21
|
for_replace = \
|
39
22
|
if read_attribute(self.class.ancestry_field).blank?
|
40
|
-
|
23
|
+
id.to_s
|
41
24
|
else
|
42
|
-
"#{read_attribute self.class.ancestry_field
|
25
|
+
"#{read_attribute self.class.ancestry_field}/#{id}"
|
43
26
|
end
|
44
27
|
new_ancestry = descendant.read_attribute(descendant.class.ancestry_field).gsub(/^#{self.child_ancestry}/, for_replace)
|
45
28
|
descendant.update_attribute(self.base_class.ancestry_field, new_ancestry)
|
@@ -85,19 +68,19 @@ module Mongoid
|
|
85
68
|
raise Error.new('No child ancestry for new record. Save record before performing tree operations.') if new_record?
|
86
69
|
|
87
70
|
if self.send("#{self.base_class.ancestry_field}_was").blank?
|
88
|
-
|
71
|
+
id.to_s
|
89
72
|
else
|
90
|
-
"#{self.send "#{self.base_class.ancestry_field}_was"}/#{
|
73
|
+
"#{self.send "#{self.base_class.ancestry_field}_was"}/#{id}"
|
91
74
|
end
|
92
75
|
end
|
93
76
|
|
94
77
|
# Ancestors
|
95
78
|
def ancestor_ids
|
96
|
-
read_attribute(self.base_class.ancestry_field).to_s.split('/').map{ |
|
79
|
+
read_attribute(self.base_class.ancestry_field).to_s.split('/').map { |id| cast_primary_key(id) }
|
97
80
|
end
|
98
81
|
|
99
82
|
def ancestor_conditions
|
100
|
-
{
|
83
|
+
{ :_id.in => ancestor_ids }
|
101
84
|
end
|
102
85
|
|
103
86
|
def ancestors depth_options = {}
|
@@ -105,11 +88,11 @@ module Mongoid
|
|
105
88
|
end
|
106
89
|
|
107
90
|
def path_ids
|
108
|
-
ancestor_ids + [
|
91
|
+
ancestor_ids + [id]
|
109
92
|
end
|
110
93
|
|
111
94
|
def path_conditions
|
112
|
-
{
|
95
|
+
{ :_id.in => path_ids }
|
113
96
|
end
|
114
97
|
|
115
98
|
def path depth_options = {}
|
@@ -130,7 +113,7 @@ module Mongoid
|
|
130
113
|
end
|
131
114
|
|
132
115
|
def parent_id= parent_id
|
133
|
-
self.parent = parent_id.blank? ? nil : self.base_class.
|
116
|
+
self.parent = parent_id.blank? ? nil : self.base_class.find(parent_id)
|
134
117
|
end
|
135
118
|
|
136
119
|
def parent_id
|
@@ -138,16 +121,16 @@ module Mongoid
|
|
138
121
|
end
|
139
122
|
|
140
123
|
def parent
|
141
|
-
parent_id.blank? ? nil : self.base_class.
|
124
|
+
parent_id.blank? ? nil : self.base_class.find(parent_id)
|
142
125
|
end
|
143
126
|
|
144
127
|
# Root
|
145
128
|
def root_id
|
146
|
-
ancestor_ids.empty? ?
|
129
|
+
ancestor_ids.empty? ? id : ancestor_ids.first
|
147
130
|
end
|
148
131
|
|
149
132
|
def root
|
150
|
-
(root_id ==
|
133
|
+
(root_id == id) ? self : self.base_class.find(root_id)
|
151
134
|
end
|
152
135
|
|
153
136
|
def is_root?
|
@@ -164,7 +147,7 @@ module Mongoid
|
|
164
147
|
end
|
165
148
|
|
166
149
|
def child_ids
|
167
|
-
children.only(
|
150
|
+
children.only(:_id).map(&:id)
|
168
151
|
end
|
169
152
|
|
170
153
|
def has_children?
|
@@ -185,7 +168,7 @@ module Mongoid
|
|
185
168
|
end
|
186
169
|
|
187
170
|
def sibling_ids
|
188
|
-
siblings.only(
|
171
|
+
siblings.only(:_id).map(&:id)
|
189
172
|
end
|
190
173
|
|
191
174
|
def has_siblings?
|
@@ -198,7 +181,6 @@ module Mongoid
|
|
198
181
|
|
199
182
|
# Descendants
|
200
183
|
def descendant_conditions
|
201
|
-
#["#{self.base_class.ancestry_field} like ? or #{self.base_class.ancestry_column} = ?", "#{child_ancestry}/%", child_ancestry]
|
202
184
|
[
|
203
185
|
{ self.base_class.ancestry_field => /^#{child_ancestry}\// },
|
204
186
|
{ self.base_class.ancestry_field => child_ancestry }
|
@@ -210,17 +192,16 @@ module Mongoid
|
|
210
192
|
end
|
211
193
|
|
212
194
|
def descendant_ids depth_options = {}
|
213
|
-
descendants(depth_options).only(
|
195
|
+
descendants(depth_options).only(:_id).map(&:id)
|
214
196
|
end
|
215
197
|
|
216
198
|
# Subtree
|
217
199
|
def subtree_conditions
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
]
|
200
|
+
[
|
201
|
+
{ :_id => id },
|
202
|
+
{ self.base_class.ancestry_field => /^#{child_ancestry}\// },
|
203
|
+
{ self.base_class.ancestry_field => child_ancestry }
|
204
|
+
]
|
224
205
|
end
|
225
206
|
|
226
207
|
def subtree depth_options = {}
|
@@ -228,7 +209,7 @@ module Mongoid
|
|
228
209
|
end
|
229
210
|
|
230
211
|
def subtree_ids depth_options = {}
|
231
|
-
subtree(depth_options).
|
212
|
+
subtree(depth_options).only(:_id).map(&:id)
|
232
213
|
end
|
233
214
|
|
234
215
|
# Callback disabling
|
@@ -241,6 +222,22 @@ module Mongoid
|
|
241
222
|
def ancestry_callbacks_disabled?
|
242
223
|
!!@disable_ancestry_callbacks
|
243
224
|
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
def cast_primary_key(key)
|
229
|
+
if primary_key_type == Integer
|
230
|
+
key.to_i
|
231
|
+
elsif primary_key_type == BSON::ObjectId && key =~ /[a-z0-9]{24}/
|
232
|
+
BSON::ObjectId.convert(self, key)
|
233
|
+
else
|
234
|
+
key
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def primary_key_type
|
239
|
+
@primary_key_type ||= self.base_class.fields['_id'].options[:type]
|
240
|
+
end
|
244
241
|
end
|
245
242
|
end
|
246
243
|
end
|
data/mongoid-ancestry.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongoid-ancestry}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Stefan Kroes", "Anton Orel"]
|
12
|
-
s.date = %q{2011-04-
|
12
|
+
s.date = %q{2011-04-19}
|
13
13
|
s.description = %q{Organise Mongoid model into a tree structure}
|
14
14
|
s.email = %q{eagle.anton@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -67,6 +67,12 @@ Gem::Specification.new do |s|
|
|
67
67
|
s.add_development_dependency(%q<libnotify>, ["~> 0.3"])
|
68
68
|
s.add_development_dependency(%q<rb-inotify>, ["~> 0.8"])
|
69
69
|
s.add_development_dependency(%q<fuubar>, ["~> 0.0.4"])
|
70
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.5"])
|
71
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
72
|
+
s.add_development_dependency(%q<guard-rspec>, ["~> 0.2"])
|
73
|
+
s.add_development_dependency(%q<libnotify>, ["~> 0.3"])
|
74
|
+
s.add_development_dependency(%q<rb-inotify>, ["~> 0.8"])
|
75
|
+
s.add_development_dependency(%q<fuubar>, ["~> 0.0.4"])
|
70
76
|
s.add_runtime_dependency(%q<mongoid>, ["~> 2.0"])
|
71
77
|
s.add_runtime_dependency(%q<bson_ext>, ["~> 1.3"])
|
72
78
|
s.add_development_dependency(%q<rspec>, ["~> 2.5"])
|
@@ -89,6 +95,12 @@ Gem::Specification.new do |s|
|
|
89
95
|
s.add_dependency(%q<libnotify>, ["~> 0.3"])
|
90
96
|
s.add_dependency(%q<rb-inotify>, ["~> 0.8"])
|
91
97
|
s.add_dependency(%q<fuubar>, ["~> 0.0.4"])
|
98
|
+
s.add_dependency(%q<rspec>, ["~> 2.5"])
|
99
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
100
|
+
s.add_dependency(%q<guard-rspec>, ["~> 0.2"])
|
101
|
+
s.add_dependency(%q<libnotify>, ["~> 0.3"])
|
102
|
+
s.add_dependency(%q<rb-inotify>, ["~> 0.8"])
|
103
|
+
s.add_dependency(%q<fuubar>, ["~> 0.0.4"])
|
92
104
|
s.add_dependency(%q<mongoid>, ["~> 2.0"])
|
93
105
|
s.add_dependency(%q<bson_ext>, ["~> 1.3"])
|
94
106
|
s.add_dependency(%q<rspec>, ["~> 2.5"])
|
@@ -112,6 +124,12 @@ Gem::Specification.new do |s|
|
|
112
124
|
s.add_dependency(%q<libnotify>, ["~> 0.3"])
|
113
125
|
s.add_dependency(%q<rb-inotify>, ["~> 0.8"])
|
114
126
|
s.add_dependency(%q<fuubar>, ["~> 0.0.4"])
|
127
|
+
s.add_dependency(%q<rspec>, ["~> 2.5"])
|
128
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
129
|
+
s.add_dependency(%q<guard-rspec>, ["~> 0.2"])
|
130
|
+
s.add_dependency(%q<libnotify>, ["~> 0.3"])
|
131
|
+
s.add_dependency(%q<rb-inotify>, ["~> 0.8"])
|
132
|
+
s.add_dependency(%q<fuubar>, ["~> 0.0.4"])
|
115
133
|
s.add_dependency(%q<mongoid>, ["~> 2.0"])
|
116
134
|
s.add_dependency(%q<bson_ext>, ["~> 1.3"])
|
117
135
|
s.add_dependency(%q<rspec>, ["~> 2.5"])
|
@@ -31,7 +31,7 @@ describe MongoidAncestry do
|
|
31
31
|
|
32
32
|
it "should be arranged" do
|
33
33
|
subject.with_model :depth => 3, :width => 3 do |model, roots|
|
34
|
-
id_sorter = Proc.new
|
34
|
+
id_sorter = Proc.new {|a, b|; a.to_param <=> b.to_param }
|
35
35
|
arranged_nodes = model.arrange
|
36
36
|
arranged_nodes.size.should eql(3)
|
37
37
|
arranged_nodes.each do |node, children|
|
@@ -48,8 +48,8 @@ describe MongoidAncestry do
|
|
48
48
|
|
49
49
|
it "should have arrange order option" do
|
50
50
|
subject.with_model :width => 3, :depth => 3 do |model, roots|
|
51
|
-
descending_nodes_lvl0 = model.arrange :order => [:
|
52
|
-
ascending_nodes_lvl0 = model.arrange :order => [:
|
51
|
+
descending_nodes_lvl0 = model.arrange :order => [:_id, :desc]
|
52
|
+
ascending_nodes_lvl0 = model.arrange :order => [:_id, :asc]
|
53
53
|
|
54
54
|
descending_nodes_lvl0.keys.zip(ascending_nodes_lvl0.keys.reverse).each do |descending_node, ascending_node|
|
55
55
|
ascending_node.should eql(descending_node)
|
@@ -105,14 +105,6 @@ describe MongoidAncestry do
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
it "should find record by uid" do
|
109
|
-
subject.with_model do |model|
|
110
|
-
expect { model.find_by_uid!(1)}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
111
|
-
instance = model.create!
|
112
|
-
expect { model.find_by_uid!(1).should eql(instance)}.to_not raise_error(Mongoid::Errors::DocumentNotFound)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
108
|
it "should check that there are no errors on a valid tree" do
|
117
109
|
subject.with_model :width => 3, :depth => 3 do |model, roots|
|
118
110
|
expect { model.check_ancestry_integrity! }.to_not raise_error(Mongoid::Ancestry::Error)
|
@@ -130,7 +122,10 @@ describe MongoidAncestry do
|
|
130
122
|
|
131
123
|
it "should check detection of non-existent ancestor" do
|
132
124
|
subject.with_model :width => 3, :depth => 3 do |model, roots|
|
133
|
-
roots.first.first
|
125
|
+
node = roots.first.first
|
126
|
+
node.without_ancestry_callbacks do
|
127
|
+
node.update_attribute model.ancestry_field, 35
|
128
|
+
end
|
134
129
|
expect { model.check_ancestry_integrity! }.to raise_error(Mongoid::Ancestry::IntegrityError)
|
135
130
|
model.check_ancestry_integrity!(:report => :list).size.should eql(1)
|
136
131
|
end
|
@@ -139,7 +134,7 @@ describe MongoidAncestry do
|
|
139
134
|
it "should check detection of cyclic ancestry" do
|
140
135
|
subject.with_model :width => 3, :depth => 3 do |model, roots|
|
141
136
|
node = roots.first.first
|
142
|
-
node.update_attribute model.ancestry_field, node.
|
137
|
+
node.update_attribute model.ancestry_field, node.id
|
143
138
|
expect { model.check_ancestry_integrity! }.to raise_error(Mongoid::Ancestry::IntegrityError)
|
144
139
|
model.check_ancestry_integrity!(:report => :list).size.should eql(1)
|
145
140
|
end
|
@@ -148,7 +143,7 @@ describe MongoidAncestry do
|
|
148
143
|
it "should check detection of conflicting parent id" do
|
149
144
|
subject.with_model do |model|
|
150
145
|
model.destroy_all
|
151
|
-
model.create!(model.ancestry_field => model.create!(model.ancestry_field => model.create!(model.ancestry_field => nil).
|
146
|
+
model.create!(model.ancestry_field => model.create!(model.ancestry_field => model.create!(model.ancestry_field => nil).id).id)
|
152
147
|
expect { model.check_ancestry_integrity! }.to raise_error(Mongoid::Ancestry::IntegrityError)
|
153
148
|
model.check_ancestry_integrity!(:report => :list).size.should eql(1)
|
154
149
|
end
|
@@ -177,7 +172,7 @@ describe MongoidAncestry do
|
|
177
172
|
it "should check that integrity is restored for cyclic ancestry" do
|
178
173
|
subject.with_model :width => 3, :depth => 3 do |model, roots|
|
179
174
|
node = roots.first.first
|
180
|
-
node.update_attribute model.ancestry_field, node.
|
175
|
+
node.update_attribute model.ancestry_field, node.id
|
181
176
|
assert_integrity_restoration model
|
182
177
|
end
|
183
178
|
end
|
@@ -185,7 +180,7 @@ describe MongoidAncestry do
|
|
185
180
|
it "should check that integrity is restored for conflicting parent id" do
|
186
181
|
subject.with_model do |model|
|
187
182
|
model.destroy_all
|
188
|
-
model.create!(model.ancestry_field => model.create!(model.ancestry_field => model.create!(model.ancestry_field => nil).
|
183
|
+
model.create!(model.ancestry_field => model.create!(model.ancestry_field => model.create!(model.ancestry_field => nil).id).id)
|
189
184
|
assert_integrity_restoration model
|
190
185
|
end
|
191
186
|
end
|
@@ -4,110 +4,85 @@ describe MongoidAncestry do
|
|
4
4
|
|
5
5
|
subject { MongoidAncestry }
|
6
6
|
|
7
|
-
it "should be saved with unique id for new records" do
|
8
|
-
subject.with_model do |model|
|
9
|
-
new_record = model.create!
|
10
|
-
new_record.uid.should eql(1)
|
11
|
-
expect { new_record.save }.to_not change(new_record, :uid)
|
12
|
-
expect { new_record.save! }.to_not change(new_record, :uid)
|
13
|
-
model.create.uid.should eql(2)
|
14
|
-
model.create!.uid.should eql(3)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should raise error on non unique id" do
|
19
|
-
subject.with_model do |model|
|
20
|
-
model.create_indexes
|
21
|
-
expect do
|
22
|
-
first_record = model.new
|
23
|
-
first_record.stub!(:set_uid => true)
|
24
|
-
first_record.save
|
25
|
-
second = model.new
|
26
|
-
second.should_receive(:set_uid).exactly(3).times.and_return(true)
|
27
|
-
second.save
|
28
|
-
end.to raise_error(Mongo::OperationFailure, /duplicate key error/)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
7
|
it "should have tree navigation" do
|
33
8
|
subject.with_model :depth => 3, :width => 3 do |model, roots|
|
34
9
|
roots.each do |lvl0_node, lvl0_children|
|
35
10
|
# Ancestors assertions
|
36
11
|
lvl0_node.ancestor_ids.should eql([])
|
37
12
|
lvl0_node.ancestors.to_a.should eql([])
|
38
|
-
lvl0_node.path_ids.should eql([lvl0_node.
|
13
|
+
lvl0_node.path_ids.should eql([lvl0_node.id])
|
39
14
|
lvl0_node.path.to_a.should eql([lvl0_node])
|
40
15
|
lvl0_node.depth.should eql(0)
|
41
16
|
# Parent assertions
|
42
17
|
lvl0_node.parent_id.should be_nil
|
43
18
|
lvl0_node.parent.should be_nil
|
44
19
|
# Root assertions
|
45
|
-
lvl0_node.root_id.should eql(lvl0_node.
|
20
|
+
lvl0_node.root_id.should eql(lvl0_node.id)
|
46
21
|
lvl0_node.root.should eql(lvl0_node)
|
47
22
|
lvl0_node.is_root?.should be_true
|
48
23
|
# Children assertions
|
49
|
-
lvl0_node.child_ids.should eql(lvl0_children.map(&:first).map(&:
|
24
|
+
lvl0_node.child_ids.should eql(lvl0_children.map(&:first).map(&:id))
|
50
25
|
lvl0_node.children.to_a.should eql(lvl0_children.map(&:first))
|
51
26
|
lvl0_node.has_children?.should be_true
|
52
27
|
lvl0_node.is_childless?.should be_false
|
53
28
|
# Siblings assertions
|
54
|
-
lvl0_node.sibling_ids.should eql(roots.map(&:first).map(&:
|
29
|
+
lvl0_node.sibling_ids.should eql(roots.map(&:first).map(&:id))
|
55
30
|
lvl0_node.siblings.to_a.should eql(roots.map(&:first))
|
56
31
|
lvl0_node.has_siblings?.should be_true
|
57
32
|
lvl0_node.is_only_child?.should be_false
|
58
33
|
# Descendants assertions
|
59
34
|
descendants = model.all.find_all do |node|
|
60
|
-
node.ancestor_ids.include?(lvl0_node.
|
35
|
+
node.ancestor_ids.include?(lvl0_node.id)
|
61
36
|
end
|
62
|
-
lvl0_node.descendant_ids.should eql(descendants.map(&:
|
37
|
+
lvl0_node.descendant_ids.should eql(descendants.map(&:id))
|
63
38
|
lvl0_node.descendants.to_a.should eql(descendants)
|
64
39
|
lvl0_node.subtree.to_a.should eql([lvl0_node] + descendants)
|
65
40
|
|
66
41
|
lvl0_children.each do |lvl1_node, lvl1_children|
|
67
42
|
# Ancestors assertions
|
68
|
-
lvl1_node.ancestor_ids.should eql([lvl0_node.
|
43
|
+
lvl1_node.ancestor_ids.should eql([lvl0_node.id])
|
69
44
|
lvl1_node.ancestors.to_a.should eql([lvl0_node])
|
70
|
-
lvl1_node.path_ids.should eql([lvl0_node.
|
45
|
+
lvl1_node.path_ids.should eql([lvl0_node.id, lvl1_node.id])
|
71
46
|
lvl1_node.path.to_a.should eql([lvl0_node, lvl1_node])
|
72
47
|
lvl1_node.depth.should eql(1)
|
73
48
|
# Parent assertions
|
74
|
-
lvl1_node.parent_id.should eql(lvl0_node.
|
49
|
+
lvl1_node.parent_id.should eql(lvl0_node.id)
|
75
50
|
lvl1_node.parent.should eql(lvl0_node)
|
76
51
|
# Root assertions
|
77
|
-
lvl1_node.root_id.should eql(lvl0_node.
|
52
|
+
lvl1_node.root_id.should eql(lvl0_node.id)
|
78
53
|
lvl1_node.root.should eql(lvl0_node)
|
79
54
|
lvl1_node.is_root?.should be_false
|
80
55
|
# Children assertions
|
81
|
-
lvl1_node.child_ids.should eql(lvl1_children.map(&:first).map(&:
|
56
|
+
lvl1_node.child_ids.should eql(lvl1_children.map(&:first).map(&:id))
|
82
57
|
lvl1_node.children.to_a.should eql(lvl1_children.map(&:first))
|
83
58
|
lvl1_node.has_children?.should be_true
|
84
59
|
lvl1_node.is_childless?.should be_false
|
85
60
|
# Siblings assertions
|
86
|
-
lvl1_node.sibling_ids.should eql(lvl0_children.map(&:first).map(&:
|
61
|
+
lvl1_node.sibling_ids.should eql(lvl0_children.map(&:first).map(&:id))
|
87
62
|
lvl1_node.siblings.to_a.should eql(lvl0_children.map(&:first))
|
88
63
|
lvl1_node.has_siblings?.should be_true
|
89
64
|
lvl1_node.is_only_child?.should be_false
|
90
65
|
# Descendants assertions
|
91
66
|
descendants = model.all.find_all do |node|
|
92
|
-
node.ancestor_ids.include? lvl1_node.
|
67
|
+
node.ancestor_ids.include? lvl1_node.id
|
93
68
|
end
|
94
69
|
|
95
|
-
lvl1_node.descendant_ids.should eql(descendants.map(&:
|
70
|
+
lvl1_node.descendant_ids.should eql(descendants.map(&:id))
|
96
71
|
lvl1_node.descendants.to_a.should eql(descendants)
|
97
72
|
lvl1_node.subtree.to_a.should eql([lvl1_node] + descendants)
|
98
73
|
|
99
74
|
lvl1_children.each do |lvl2_node, lvl2_children|
|
100
75
|
# Ancestors assertions
|
101
|
-
lvl2_node.ancestor_ids.should eql([lvl0_node.
|
76
|
+
lvl2_node.ancestor_ids.should eql([lvl0_node.id, lvl1_node.id])
|
102
77
|
lvl2_node.ancestors.to_a.should eql([lvl0_node, lvl1_node])
|
103
|
-
lvl2_node.path_ids.should eql([lvl0_node.
|
78
|
+
lvl2_node.path_ids.should eql([lvl0_node.id, lvl1_node.id, lvl2_node.id])
|
104
79
|
lvl2_node.path.to_a.should eql([lvl0_node, lvl1_node, lvl2_node])
|
105
80
|
lvl2_node.depth.should eql(2)
|
106
81
|
# Parent assertions
|
107
|
-
lvl2_node.parent_id.should eql(lvl1_node.
|
82
|
+
lvl2_node.parent_id.should eql(lvl1_node.id)
|
108
83
|
lvl2_node.parent.should eql(lvl1_node)
|
109
84
|
# Root assertions
|
110
|
-
lvl2_node.root_id.should eql(lvl0_node.
|
85
|
+
lvl2_node.root_id.should eql(lvl0_node.id)
|
111
86
|
lvl2_node.root.should eql(lvl0_node)
|
112
87
|
lvl2_node.is_root?.should be_false
|
113
88
|
# Children assertions
|
@@ -116,7 +91,7 @@ describe MongoidAncestry do
|
|
116
91
|
lvl2_node.has_children?.should be_false
|
117
92
|
lvl2_node.is_childless?.should be_true
|
118
93
|
# Siblings assertions
|
119
|
-
lvl2_node.sibling_ids.should eql(lvl1_children.map(&:first).map(&:
|
94
|
+
lvl2_node.sibling_ids.should eql(lvl1_children.map(&:first).map(&:id))
|
120
95
|
lvl2_node.siblings.to_a.should eql(lvl1_children.map(&:first))
|
121
96
|
lvl2_node.has_siblings?.should be_true
|
122
97
|
lvl2_node.is_only_child?.should be_false
|
@@ -124,7 +99,7 @@ describe MongoidAncestry do
|
|
124
99
|
descendants = model.all.find_all do |node|
|
125
100
|
node.ancestor_ids.include? lvl2_node.id
|
126
101
|
end
|
127
|
-
lvl2_node.descendant_ids.should eql(descendants.map(&:
|
102
|
+
lvl2_node.descendant_ids.should eql(descendants.map(&:id))
|
128
103
|
lvl2_node.descendants.to_a.should eql(descendants)
|
129
104
|
lvl2_node.subtree.to_a.should eql([lvl2_node] + descendants)
|
130
105
|
end
|
@@ -138,12 +113,12 @@ describe MongoidAncestry do
|
|
138
113
|
node = model.create
|
139
114
|
['3', '10/2', '1/4/30', nil].each do |value|
|
140
115
|
node.send :write_attribute, model.ancestry_field, value
|
141
|
-
node.
|
116
|
+
node.should be_valid
|
142
117
|
node.errors[model.ancestry_field].blank?.should be_true
|
143
118
|
end
|
144
|
-
['1/3/', '/2/3', '
|
119
|
+
['1/3/', '/2/3', 'A/b', '-34', '/54'].each do |value|
|
145
120
|
node.send :write_attribute, model.ancestry_field, value
|
146
|
-
node.
|
121
|
+
node.should_not be_valid
|
147
122
|
node.errors[model.ancestry_field].blank?.should be_false
|
148
123
|
end
|
149
124
|
end
|
@@ -153,26 +128,26 @@ describe MongoidAncestry do
|
|
153
128
|
subject.with_model :depth => 3, :width => 3 do |model, roots|
|
154
129
|
root1, root2, root3 = roots.map(&:first)
|
155
130
|
|
156
|
-
descendants = root1.descendants.asc(:
|
131
|
+
descendants = root1.descendants.asc(:_id).map(&:to_param)
|
157
132
|
expect {
|
158
133
|
root1.parent = root2
|
159
134
|
root1.save!
|
160
|
-
root1.descendants.asc(:
|
135
|
+
root1.descendants.asc(:_id).map(&:to_param).should eql(descendants)
|
161
136
|
}.to change(root2.descendants, 'size').by(root1.subtree.size)
|
162
137
|
|
163
|
-
descendants = root2.descendants.asc(:
|
138
|
+
descendants = root2.descendants.asc(:_id).map(&:to_param)
|
164
139
|
expect {
|
165
140
|
root2.parent = root3
|
166
141
|
root2.save!
|
167
|
-
root2.descendants.asc(:
|
142
|
+
root2.descendants.asc(:_id).map(&:to_param).should eql(descendants)
|
168
143
|
}.to change(root3.descendants, 'size').by(root2.subtree.size)
|
169
144
|
|
170
|
-
descendants = root1.descendants.asc(:
|
145
|
+
descendants = root1.descendants.asc(:_id).map(&:to_param)
|
171
146
|
expect {
|
172
147
|
expect {
|
173
148
|
root1.parent = nil
|
174
149
|
root1.save!
|
175
|
-
root1.descendants.asc(:
|
150
|
+
root1.descendants.asc(:_id).map(&:to_param).should eql(descendants)
|
176
151
|
}.to change(root3.descendants, 'size').by(-root1.subtree.size)
|
177
152
|
}.to change(root2.descendants, 'size').by(-root1.subtree.size)
|
178
153
|
end
|
@@ -10,13 +10,6 @@ describe MongoidAncestry do
|
|
10
10
|
it "should have ancestry fields" do
|
11
11
|
subject.with_model do |model|
|
12
12
|
model.fields['ancestry'].options[:type].should eql(String)
|
13
|
-
model.fields['uid'].options[:type].should eql(Integer)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should have ancestry indexes" do
|
18
|
-
subject.with_model do |model|
|
19
|
-
model.index_options.should have_key(:uid)
|
20
13
|
end
|
21
14
|
end
|
22
15
|
|
data/spec/support/models.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-ancestry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,12 +10,12 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-19 00:00:00.000000000 +04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: mongoid-ancestry
|
18
|
-
requirement: &
|
18
|
+
requirement: &15269160 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ! '>='
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: '0'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *15269160
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
|
-
requirement: &
|
29
|
+
requirement: &15268300 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: '2.5'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *15268300
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: bundler
|
40
|
-
requirement: &
|
40
|
+
requirement: &15267460 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '1.0'
|
46
46
|
type: :development
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *15267460
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: guard-rspec
|
51
|
-
requirement: &
|
51
|
+
requirement: &15201860 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ~>
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: '0.2'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *15201860
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: libnotify
|
62
|
-
requirement: &
|
62
|
+
requirement: &15200920 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ~>
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: '0.3'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *15200920
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: rb-inotify
|
73
|
-
requirement: &
|
73
|
+
requirement: &15200100 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ~>
|
@@ -78,10 +78,10 @@ dependencies:
|
|
78
78
|
version: '0.8'
|
79
79
|
type: :development
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *15200100
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: fuubar
|
84
|
-
requirement: &
|
84
|
+
requirement: &15199500 !ruby/object:Gem::Requirement
|
85
85
|
none: false
|
86
86
|
requirements:
|
87
87
|
- - ~>
|
@@ -89,10 +89,10 @@ dependencies:
|
|
89
89
|
version: 0.0.4
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
|
-
version_requirements: *
|
92
|
+
version_requirements: *15199500
|
93
93
|
- !ruby/object:Gem::Dependency
|
94
94
|
name: rspec
|
95
|
-
requirement: &
|
95
|
+
requirement: &15198860 !ruby/object:Gem::Requirement
|
96
96
|
none: false
|
97
97
|
requirements:
|
98
98
|
- - ~>
|
@@ -100,10 +100,10 @@ dependencies:
|
|
100
100
|
version: '2.5'
|
101
101
|
type: :development
|
102
102
|
prerelease: false
|
103
|
-
version_requirements: *
|
103
|
+
version_requirements: *15198860
|
104
104
|
- !ruby/object:Gem::Dependency
|
105
105
|
name: bundler
|
106
|
-
requirement: &
|
106
|
+
requirement: &15198340 !ruby/object:Gem::Requirement
|
107
107
|
none: false
|
108
108
|
requirements:
|
109
109
|
- - ~>
|
@@ -111,10 +111,10 @@ dependencies:
|
|
111
111
|
version: '1.0'
|
112
112
|
type: :development
|
113
113
|
prerelease: false
|
114
|
-
version_requirements: *
|
114
|
+
version_requirements: *15198340
|
115
115
|
- !ruby/object:Gem::Dependency
|
116
116
|
name: guard-rspec
|
117
|
-
requirement: &
|
117
|
+
requirement: &15197640 !ruby/object:Gem::Requirement
|
118
118
|
none: false
|
119
119
|
requirements:
|
120
120
|
- - ~>
|
@@ -122,10 +122,10 @@ dependencies:
|
|
122
122
|
version: '0.2'
|
123
123
|
type: :development
|
124
124
|
prerelease: false
|
125
|
-
version_requirements: *
|
125
|
+
version_requirements: *15197640
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: libnotify
|
128
|
-
requirement: &
|
128
|
+
requirement: &15196720 !ruby/object:Gem::Requirement
|
129
129
|
none: false
|
130
130
|
requirements:
|
131
131
|
- - ~>
|
@@ -133,10 +133,10 @@ dependencies:
|
|
133
133
|
version: '0.3'
|
134
134
|
type: :development
|
135
135
|
prerelease: false
|
136
|
-
version_requirements: *
|
136
|
+
version_requirements: *15196720
|
137
137
|
- !ruby/object:Gem::Dependency
|
138
138
|
name: rb-inotify
|
139
|
-
requirement: &
|
139
|
+
requirement: &15195680 !ruby/object:Gem::Requirement
|
140
140
|
none: false
|
141
141
|
requirements:
|
142
142
|
- - ~>
|
@@ -144,10 +144,10 @@ dependencies:
|
|
144
144
|
version: '0.8'
|
145
145
|
type: :development
|
146
146
|
prerelease: false
|
147
|
-
version_requirements: *
|
147
|
+
version_requirements: *15195680
|
148
148
|
- !ruby/object:Gem::Dependency
|
149
149
|
name: fuubar
|
150
|
-
requirement: &
|
150
|
+
requirement: &15195100 !ruby/object:Gem::Requirement
|
151
151
|
none: false
|
152
152
|
requirements:
|
153
153
|
- - ~>
|
@@ -155,10 +155,76 @@ dependencies:
|
|
155
155
|
version: 0.0.4
|
156
156
|
type: :development
|
157
157
|
prerelease: false
|
158
|
-
version_requirements: *
|
158
|
+
version_requirements: *15195100
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: rspec
|
161
|
+
requirement: &15194480 !ruby/object:Gem::Requirement
|
162
|
+
none: false
|
163
|
+
requirements:
|
164
|
+
- - ~>
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '2.5'
|
167
|
+
type: :development
|
168
|
+
prerelease: false
|
169
|
+
version_requirements: *15194480
|
170
|
+
- !ruby/object:Gem::Dependency
|
171
|
+
name: bundler
|
172
|
+
requirement: &14985320 !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
174
|
+
requirements:
|
175
|
+
- - ~>
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '1.0'
|
178
|
+
type: :development
|
179
|
+
prerelease: false
|
180
|
+
version_requirements: *14985320
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: guard-rspec
|
183
|
+
requirement: &14984380 !ruby/object:Gem::Requirement
|
184
|
+
none: false
|
185
|
+
requirements:
|
186
|
+
- - ~>
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0.2'
|
189
|
+
type: :development
|
190
|
+
prerelease: false
|
191
|
+
version_requirements: *14984380
|
192
|
+
- !ruby/object:Gem::Dependency
|
193
|
+
name: libnotify
|
194
|
+
requirement: &14982580 !ruby/object:Gem::Requirement
|
195
|
+
none: false
|
196
|
+
requirements:
|
197
|
+
- - ~>
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0.3'
|
200
|
+
type: :development
|
201
|
+
prerelease: false
|
202
|
+
version_requirements: *14982580
|
203
|
+
- !ruby/object:Gem::Dependency
|
204
|
+
name: rb-inotify
|
205
|
+
requirement: &14980880 !ruby/object:Gem::Requirement
|
206
|
+
none: false
|
207
|
+
requirements:
|
208
|
+
- - ~>
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
version: '0.8'
|
211
|
+
type: :development
|
212
|
+
prerelease: false
|
213
|
+
version_requirements: *14980880
|
214
|
+
- !ruby/object:Gem::Dependency
|
215
|
+
name: fuubar
|
216
|
+
requirement: &14978240 !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ~>
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: 0.0.4
|
222
|
+
type: :development
|
223
|
+
prerelease: false
|
224
|
+
version_requirements: *14978240
|
159
225
|
- !ruby/object:Gem::Dependency
|
160
226
|
name: mongoid
|
161
|
-
requirement: &
|
227
|
+
requirement: &14963400 !ruby/object:Gem::Requirement
|
162
228
|
none: false
|
163
229
|
requirements:
|
164
230
|
- - ~>
|
@@ -166,10 +232,10 @@ dependencies:
|
|
166
232
|
version: '2.0'
|
167
233
|
type: :runtime
|
168
234
|
prerelease: false
|
169
|
-
version_requirements: *
|
235
|
+
version_requirements: *14963400
|
170
236
|
- !ruby/object:Gem::Dependency
|
171
237
|
name: bson_ext
|
172
|
-
requirement: &
|
238
|
+
requirement: &14961860 !ruby/object:Gem::Requirement
|
173
239
|
none: false
|
174
240
|
requirements:
|
175
241
|
- - ~>
|
@@ -177,10 +243,10 @@ dependencies:
|
|
177
243
|
version: '1.3'
|
178
244
|
type: :runtime
|
179
245
|
prerelease: false
|
180
|
-
version_requirements: *
|
246
|
+
version_requirements: *14961860
|
181
247
|
- !ruby/object:Gem::Dependency
|
182
248
|
name: rspec
|
183
|
-
requirement: &
|
249
|
+
requirement: &14960500 !ruby/object:Gem::Requirement
|
184
250
|
none: false
|
185
251
|
requirements:
|
186
252
|
- - ~>
|
@@ -188,10 +254,10 @@ dependencies:
|
|
188
254
|
version: '2.5'
|
189
255
|
type: :development
|
190
256
|
prerelease: false
|
191
|
-
version_requirements: *
|
257
|
+
version_requirements: *14960500
|
192
258
|
- !ruby/object:Gem::Dependency
|
193
259
|
name: bundler
|
194
|
-
requirement: &
|
260
|
+
requirement: &14959360 !ruby/object:Gem::Requirement
|
195
261
|
none: false
|
196
262
|
requirements:
|
197
263
|
- - ~>
|
@@ -199,10 +265,10 @@ dependencies:
|
|
199
265
|
version: '1.0'
|
200
266
|
type: :development
|
201
267
|
prerelease: false
|
202
|
-
version_requirements: *
|
268
|
+
version_requirements: *14959360
|
203
269
|
- !ruby/object:Gem::Dependency
|
204
270
|
name: guard-rspec
|
205
|
-
requirement: &
|
271
|
+
requirement: &14958700 !ruby/object:Gem::Requirement
|
206
272
|
none: false
|
207
273
|
requirements:
|
208
274
|
- - ~>
|
@@ -210,10 +276,10 @@ dependencies:
|
|
210
276
|
version: '0.2'
|
211
277
|
type: :development
|
212
278
|
prerelease: false
|
213
|
-
version_requirements: *
|
279
|
+
version_requirements: *14958700
|
214
280
|
- !ruby/object:Gem::Dependency
|
215
281
|
name: libnotify
|
216
|
-
requirement: &
|
282
|
+
requirement: &14958060 !ruby/object:Gem::Requirement
|
217
283
|
none: false
|
218
284
|
requirements:
|
219
285
|
- - ~>
|
@@ -221,10 +287,10 @@ dependencies:
|
|
221
287
|
version: '0.3'
|
222
288
|
type: :development
|
223
289
|
prerelease: false
|
224
|
-
version_requirements: *
|
290
|
+
version_requirements: *14958060
|
225
291
|
- !ruby/object:Gem::Dependency
|
226
292
|
name: rb-inotify
|
227
|
-
requirement: &
|
293
|
+
requirement: &14957520 !ruby/object:Gem::Requirement
|
228
294
|
none: false
|
229
295
|
requirements:
|
230
296
|
- - ~>
|
@@ -232,10 +298,10 @@ dependencies:
|
|
232
298
|
version: '0.8'
|
233
299
|
type: :development
|
234
300
|
prerelease: false
|
235
|
-
version_requirements: *
|
301
|
+
version_requirements: *14957520
|
236
302
|
- !ruby/object:Gem::Dependency
|
237
303
|
name: fuubar
|
238
|
-
requirement: &
|
304
|
+
requirement: &14956920 !ruby/object:Gem::Requirement
|
239
305
|
none: false
|
240
306
|
requirements:
|
241
307
|
- - ~>
|
@@ -243,7 +309,7 @@ dependencies:
|
|
243
309
|
version: 0.0.4
|
244
310
|
type: :development
|
245
311
|
prerelease: false
|
246
|
-
version_requirements: *
|
312
|
+
version_requirements: *14956920
|
247
313
|
description: Organise Mongoid model into a tree structure
|
248
314
|
email: eagle.anton@gmail.com
|
249
315
|
executables: []
|