mongodb 0.0.13 → 2.0.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/Rakefile +3 -4
- data/lib/mongo/driver.rb +3 -3
- data/lib/mongo/driver/collection.rb +10 -22
- data/lib/mongo/driver/dynamic_finders.rb +1 -3
- data/lib/mongo/object.rb +2 -16
- data/lib/mongo/object/{object_helper.rb → collection_helper.rb} +12 -15
- data/lib/mongo/object/load.rb +22 -0
- data/lib/mongo/object/object.rb +60 -254
- data/lib/mongo/object/spec.rb +13 -3
- data/lib/mongo/object/spec/shared_object_crud.rb +124 -0
- data/lib/mongo/object/support.rb +15 -0
- data/lib/mongodb/gems.rb +1 -1
- data/spec/driver/collection_spec.rb +13 -43
- data/spec/driver/connection_spec.rb +1 -1
- data/spec/driver/database_spec.rb +1 -1
- data/spec/driver/dynamic_finders_spec.rb +4 -4
- data/spec/driver/fixes_spec.rb +2 -2
- data/spec/driver/hash_crud_spec.rb +69 -0
- data/spec/driver/spec_helper.rb +1 -3
- data/spec/migration/migration_spec.rb +4 -4
- data/spec/object/miscellaneous_spec.rb +23 -0
- data/spec/object/object_crud_spec.rb +57 -0
- data/spec/object/spec_helper.rb +1 -14
- metadata +11 -12
- data/lib/mongo/object/spec/crud_shared.rb +0 -63
- data/spec/driver/crud_spec.rb +0 -70
- data/spec/driver/hash_helper_spec.rb +0 -25
- data/spec/object/callbacks_spec.rb +0 -115
- data/spec/object/crud_spec.rb +0 -61
- data/spec/object/validation_spec.rb +0 -79
data/Rakefile
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
require 'rake_ext'
|
2
2
|
|
3
|
-
project
|
3
|
+
project \
|
4
4
|
name: "mongodb",
|
5
|
-
|
5
|
+
version: '2.0.0',
|
6
6
|
gem: true,
|
7
7
|
summary: "Persistence for any Ruby Object & Driver enhancements for MongoDB.",
|
8
8
|
|
9
9
|
author: "Alexey Petrushin",
|
10
|
-
homepage: "http://alexeypetrushin.github.com/mongodb"
|
11
|
-
)
|
10
|
+
homepage: "http://alexeypetrushin.github.com/mongodb"
|
data/lib/mongo/driver.rb
CHANGED
@@ -12,7 +12,6 @@ class Mongo::NotFound < Mongo::Error; end
|
|
12
12
|
dynamic_finders
|
13
13
|
).each{|f| require "mongo/driver/#{f}"}
|
14
14
|
|
15
|
-
# defaults
|
16
15
|
Mongo.class_eval do
|
17
16
|
class << self
|
18
17
|
def defaults; @defaults ||= {} end
|
@@ -29,7 +28,6 @@ Mongo.class_eval do
|
|
29
28
|
end
|
30
29
|
end
|
31
30
|
end
|
32
|
-
Mongo.defaults[:convert_id_to_string] = true
|
33
31
|
|
34
32
|
Mongo::Connection.send :include, Mongo::ConnectionExt
|
35
33
|
|
@@ -42,4 +40,6 @@ Mongo::Collection.class_eval do
|
|
42
40
|
alias_method "#{method}_without_ext", method
|
43
41
|
alias_method method, "#{method}_with_ext"
|
44
42
|
end
|
45
|
-
end
|
43
|
+
end
|
44
|
+
|
45
|
+
Mongo.defaults[:convert_id_to_string] = true
|
@@ -2,9 +2,8 @@ require 'set'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module Mongo::CollectionExt
|
5
|
-
#
|
6
|
-
|
7
|
-
#
|
5
|
+
# CRUD.
|
6
|
+
|
8
7
|
def save_with_ext doc, options = {}
|
9
8
|
save_without_ext doc, reverse_merge_defaults(options, :safe)
|
10
9
|
end
|
@@ -12,7 +11,7 @@ module Mongo::CollectionExt
|
|
12
11
|
def insert_with_ext args, options = {}
|
13
12
|
result = insert_without_ext args, reverse_merge_defaults(options, :safe)
|
14
13
|
|
15
|
-
#
|
14
|
+
# For some strange reason MongoDB Ruby driver
|
16
15
|
# uses Strings for all keys but _id.
|
17
16
|
# It's inconvinient, fixing it.
|
18
17
|
if Mongo.defaults[:convert_id_to_string]
|
@@ -20,7 +19,7 @@ module Mongo::CollectionExt
|
|
20
19
|
list.each{|h| h['_id'] = h.delete :_id}
|
21
20
|
end
|
22
21
|
|
23
|
-
#
|
22
|
+
# Fix for mongodriver, it will return single result if we supply [doc] as args.
|
24
23
|
(args.is_a?(Array) and !result.is_a?(Array)) ? [result] : result
|
25
24
|
end
|
26
25
|
|
@@ -43,7 +42,7 @@ module Mongo::CollectionExt
|
|
43
42
|
remove_without_ext selector, reverse_merge_defaults(options, :safe, :multi)
|
44
43
|
end
|
45
44
|
|
46
|
-
def
|
45
|
+
def delete *args
|
47
46
|
remove *args
|
48
47
|
end
|
49
48
|
|
@@ -51,9 +50,8 @@ module Mongo::CollectionExt
|
|
51
50
|
insert *args
|
52
51
|
end
|
53
52
|
|
54
|
-
#
|
55
|
-
|
56
|
-
#
|
53
|
+
# Querying.
|
54
|
+
|
57
55
|
def first selector = {}, options = {}
|
58
56
|
selector = convert_underscore_to_dollar_in_selector selector if selector.is_a? Hash
|
59
57
|
find_one selector, options
|
@@ -114,17 +112,7 @@ module Mongo::CollectionExt
|
|
114
112
|
h
|
115
113
|
end
|
116
114
|
|
117
|
-
#
|
118
|
-
# def symbolize_doc doc
|
119
|
-
# return doc unless Mongo.defaults[:symbolize]
|
120
|
-
#
|
121
|
-
# Mongo::CollectionExt.convert_doc doc do |k, v, result|
|
122
|
-
# k = k.to_sym if k.is_a? String
|
123
|
-
# result[k] = v
|
124
|
-
# end
|
125
|
-
# end
|
126
|
-
|
127
|
-
# replaces :_lt to :$lt in query
|
115
|
+
# Replaces :_lt to :$lt in query.
|
128
116
|
def convert_underscore_to_dollar_in_selector selector
|
129
117
|
return selector unless Mongo.defaults[:convert_underscore_to_dollar]
|
130
118
|
|
@@ -134,7 +122,7 @@ module Mongo::CollectionExt
|
|
134
122
|
end
|
135
123
|
end
|
136
124
|
|
137
|
-
#
|
125
|
+
# Replaces :_set to :$set in query.
|
138
126
|
def convert_underscore_to_dollar_in_update update
|
139
127
|
return update unless Mongo.defaults[:convert_underscore_to_dollar]
|
140
128
|
|
@@ -144,7 +132,7 @@ module Mongo::CollectionExt
|
|
144
132
|
end
|
145
133
|
end
|
146
134
|
|
147
|
-
#
|
135
|
+
# Walks on hash and creates another (also works with nested & arrays).
|
148
136
|
def self.convert_doc doc, &block
|
149
137
|
if doc.is_a? Hash
|
150
138
|
result = {}
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Mongo::DynamicFinders
|
2
2
|
protected
|
3
|
-
#
|
4
|
-
# first_by_field, all_by_field, each_by_field, first_by_field
|
5
|
-
#
|
3
|
+
# Dynamic finders, like `first_by_field`, `all_by_field`, `each_by_field`, `first_by_field`.
|
6
4
|
def method_missing clause, *args, &block
|
7
5
|
if clause =~ /^([a-z]_by_[a-z_])|(by_[a-z_])/
|
8
6
|
clause = clause.to_s
|
data/lib/mongo/object.rb
CHANGED
@@ -1,19 +1,5 @@
|
|
1
1
|
require 'mongo/driver'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
object
|
6
|
-
object_helper
|
7
|
-
).each{|f| require "mongo/object/#{f}"}
|
8
|
-
|
9
|
-
Mongo.defaults[:callbacks] = true
|
10
|
-
|
11
|
-
# collection
|
12
|
-
Mongo::Collection.class_eval do
|
13
|
-
include Mongo::ObjectHelper
|
14
|
-
|
15
|
-
%w(create update save destroy).each do |method|
|
16
|
-
alias_method "#{method}_without_object", method
|
17
|
-
alias_method method, "#{method}_with_object"
|
18
|
-
end
|
3
|
+
Mongo.class_eval do
|
4
|
+
autoload :Object, 'mongo/object/load'
|
19
5
|
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
module Mongo::
|
2
|
-
#
|
3
|
-
|
4
|
-
#
|
1
|
+
module Mongo::CollectionHelper
|
2
|
+
# CRUD.
|
3
|
+
|
5
4
|
def create_with_object doc, options = {}
|
6
5
|
if doc.is_a? ::Mongo::Object
|
7
6
|
doc.create_object self, options
|
@@ -28,36 +27,34 @@ module Mongo::ObjectHelper
|
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
|
-
def
|
30
|
+
def delete_with_object *args
|
32
31
|
if args.first.is_a? ::Mongo::Object
|
33
32
|
doc, options = args
|
34
33
|
options ||= {}
|
35
|
-
doc.
|
34
|
+
doc.delete_object self, options
|
36
35
|
else
|
37
|
-
|
36
|
+
delete_without_object *args
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
41
40
|
def create! *args
|
42
|
-
create(*args) || raise(Mongo::Error, "can't create #{
|
41
|
+
create(*args) || raise(Mongo::Error, "can't create #{args.inspect}!")
|
43
42
|
end
|
44
43
|
|
45
44
|
def update! *args
|
46
|
-
update(*args) || raise(Mongo::Error, "can't update #{
|
45
|
+
update(*args) || raise(Mongo::Error, "can't update #{args.inspect}!")
|
47
46
|
end
|
48
47
|
|
49
48
|
def save! *args
|
50
|
-
save(*args) || raise(Mongo::Error, "can't save #{
|
49
|
+
save(*args) || raise(Mongo::Error, "can't save #{args.inspect}!")
|
51
50
|
end
|
52
51
|
|
53
|
-
def
|
54
|
-
|
52
|
+
def delete! *args
|
53
|
+
delete(*args) || raise(Mongo::Error, "can't delete #{args.inspect}!")
|
55
54
|
end
|
56
55
|
|
56
|
+
# Querying.
|
57
57
|
|
58
|
-
#
|
59
|
-
# Querying
|
60
|
-
#
|
61
58
|
def first selector = {}, options = {}, &block
|
62
59
|
options = options.clone
|
63
60
|
if options.delete(:object) == false
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'mongo/object/support'
|
2
|
+
require 'mongo/object/object'
|
3
|
+
require 'mongo/object/collection_helper'
|
4
|
+
|
5
|
+
Mongo::Collection.class_eval do
|
6
|
+
include Mongo::CollectionHelper
|
7
|
+
|
8
|
+
%w(create update save delete).each do |method|
|
9
|
+
alias_method "#{method}_without_object", method
|
10
|
+
alias_method method, "#{method}_with_object"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# By default MongoDB automatically generates BSON::ObjectId,
|
15
|
+
# it has smaller size than string, but usually strings are more convinient to use.
|
16
|
+
# This options changes this behaviour and allows to define `generate_id` method
|
17
|
+
# on model and use it to generate ids.
|
18
|
+
Mongo.defaults[:generate_id] = false
|
19
|
+
|
20
|
+
# Size of autogenerated random string id in default `generate_id` method,
|
21
|
+
# (used only if :generate_id option if enabled).
|
22
|
+
Mongo.defaults[:random_string_id_size] = 6
|
data/lib/mongo/object/object.rb
CHANGED
@@ -1,56 +1,30 @@
|
|
1
1
|
module Mongo::Object
|
2
2
|
attr_accessor :_id, :_parent
|
3
3
|
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
def run_validations options = {}
|
10
|
-
options = ::Mongo::Object.parse_options options
|
11
|
-
begin
|
12
|
-
return false if options[:callbacks] and !::Mongo::Object.run_before_callbacks(self, :validate)
|
13
|
-
|
14
|
-
child_options = options.merge internal: true
|
15
|
-
result = [
|
16
|
-
(respond_to?(:run_model_validations) ? run_model_validations : true),
|
17
|
-
child_objects.all?{|group| group.all?{|obj| obj.valid?(child_options)}},
|
18
|
-
errors.empty?
|
19
|
-
].all?
|
4
|
+
def _id?; !!_id end
|
5
|
+
def new?; !_id end
|
6
|
+
alias_method :new_record?, :new?
|
20
7
|
|
21
|
-
|
22
|
-
|
23
|
-
result
|
24
|
-
ensure
|
25
|
-
clear_child_objects_cache unless options[:internal]
|
26
|
-
end
|
27
|
-
end
|
8
|
+
def create_object collection, options
|
9
|
+
doc = to_mongo
|
28
10
|
|
29
|
-
|
30
|
-
|
31
|
-
end
|
11
|
+
# Generating custom id if option enabled.
|
12
|
+
doc['_id'] = generate_id if Mongo.defaults[:generate_id]
|
32
13
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
collection.create(doc, options)
|
37
|
-
self._id = doc['_id']
|
38
|
-
end
|
14
|
+
id = collection.create doc, options
|
15
|
+
self._id = id
|
16
|
+
id
|
39
17
|
end
|
40
18
|
|
41
19
|
def update_object collection, options
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
collection.update({_id: id}, doc, options)
|
46
|
-
end
|
20
|
+
id = _id || "can't update object without _id (#{self})!"
|
21
|
+
doc = to_mongo
|
22
|
+
collection.update({_id: id}, doc, options)
|
47
23
|
end
|
48
24
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
collection.destroy({_id: id}, options)
|
53
|
-
end
|
25
|
+
def delete_object collection, options
|
26
|
+
id = _id || "can't delete object without _id (#{self})!"
|
27
|
+
collection.delete({_id: id}, options)
|
54
28
|
end
|
55
29
|
|
56
30
|
def save_object collection, options
|
@@ -61,124 +35,53 @@ module Mongo::Object
|
|
61
35
|
end
|
62
36
|
end
|
63
37
|
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
def parse_options options
|
70
|
-
options = options.clone
|
71
|
-
options[:validate] = true unless options.include?(:validate)
|
72
|
-
options[:callbacks] = Mongo.defaults[:callbacks] unless options.include?(:callbacks)
|
73
|
-
return options
|
74
|
-
end
|
75
|
-
|
76
|
-
def parse_mongo_options options
|
77
|
-
options = options.clone
|
78
|
-
options.delete :validate
|
79
|
-
options.delete :callbacks
|
80
|
-
options
|
81
|
-
end
|
38
|
+
# Skipping variables starting with @_, usually they
|
39
|
+
# have specific meaning and used for things like cache.
|
40
|
+
def persistent_instance_variable_names *args
|
41
|
+
instance_variables(*args).select{|n| n !~ /^@_/}
|
42
|
+
end
|
82
43
|
|
83
|
-
|
84
|
-
|
85
|
-
|
44
|
+
# Convert object to document (with nested documents & arrays).
|
45
|
+
def to_mongo
|
46
|
+
{}.tap do |h|
|
47
|
+
# Copy instance variables.
|
48
|
+
persistent_instance_variable_names.each do |iv_name|
|
49
|
+
k = iv_name.to_s[1..-1]
|
50
|
+
v = instance_variable_get iv_name
|
51
|
+
h[k] = v.to_mongo
|
86
52
|
end
|
87
|
-
end
|
88
53
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
54
|
+
# Adding _id & _class.
|
55
|
+
h['_id'] = _id if _id
|
56
|
+
h['_class'] = self.class.name || \
|
57
|
+
raise("unknow class name for model #{h.inspect}!")
|
93
58
|
end
|
59
|
+
end
|
60
|
+
alias_method :to_hash, :to_mongo
|
94
61
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
if obj.is_a? Hash
|
100
|
-
doc = {}
|
101
|
-
obj.each do |k, v|
|
102
|
-
doc[k] = to_mongo v
|
103
|
-
end
|
104
|
-
doc
|
105
|
-
elsif obj.is_a? Array
|
106
|
-
obj.collect{|v| to_mongo v}
|
107
|
-
elsif obj.is_a? Mongo::Object
|
108
|
-
doc = {}
|
109
|
-
|
110
|
-
# copying instance variables
|
111
|
-
each_instance_variable obj do |iv_name, v|
|
112
|
-
k = iv_name.to_s[1..-1]
|
113
|
-
doc[k] = to_mongo v
|
114
|
-
end
|
115
|
-
|
116
|
-
# adding _id & _class
|
117
|
-
id = instance_variable_get('@_id')
|
118
|
-
doc['_id'] = id if id
|
119
|
-
doc['_class'] = obj.class.name
|
120
|
-
|
121
|
-
doc
|
122
|
-
else # simple type
|
123
|
-
obj
|
124
|
-
end
|
125
|
-
end
|
62
|
+
# Override it to generate Your custom ids.
|
63
|
+
def generate_id
|
64
|
+
generate_random_string_id
|
65
|
+
end
|
126
66
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
r
|
134
|
-
elsif obj.is_a? Array
|
135
|
-
obj.collect{|v| convert v, method, options}
|
136
|
-
elsif obj.is_a? Mongo::Object
|
137
|
-
obj.send method, options
|
138
|
-
else # simple type
|
139
|
-
obj
|
140
|
-
end
|
141
|
-
end
|
67
|
+
def inspect
|
68
|
+
h = to_hash
|
69
|
+
h.delete '_class'
|
70
|
+
"#<#{self.class}:#{h.inspect}>"
|
71
|
+
end
|
72
|
+
alias_method :to_s, :inspect
|
142
73
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
obj.each{|v| each_object v, &block}
|
150
|
-
elsif obj.is_a? ::Mongo::Object
|
151
|
-
block.call obj
|
152
|
-
each_instance_variable obj do |iv_name, v|
|
153
|
-
each_object v, &block
|
154
|
-
end
|
155
|
-
end
|
156
|
-
nil
|
74
|
+
protected
|
75
|
+
ID_SYMBOLS = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
|
76
|
+
def generate_random_string_id
|
77
|
+
id, size = "", Mongo.defaults[:random_string_id_size]
|
78
|
+
size.times{id << ID_SYMBOLS[rand(ID_SYMBOLS.size)]}
|
79
|
+
id
|
157
80
|
end
|
158
81
|
|
82
|
+
class << self
|
159
83
|
def build doc
|
160
|
-
|
161
|
-
obj = _build doc, nil
|
162
|
-
obj.send :update_original_children! if obj.is_a? ::Mongo::Object
|
163
|
-
obj
|
164
|
-
end
|
165
|
-
|
166
|
-
def run_before_callbacks obj, method
|
167
|
-
if obj.respond_to?(:run_before_callbacks)
|
168
|
-
obj.run_before_callbacks(:save, method: :save) if method == :update or method == :create
|
169
|
-
obj.run_before_callbacks(method, method: method)
|
170
|
-
else
|
171
|
-
true
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def run_after_callbacks obj, method
|
176
|
-
if obj.respond_to?(:run_after_callbacks)
|
177
|
-
obj.run_after_callbacks(method, method: method)
|
178
|
-
obj.run_after_callbacks(:save, method: :save) if method == :update or method == :create
|
179
|
-
else
|
180
|
-
true
|
181
|
-
end
|
84
|
+
doc && _build(doc, nil)
|
182
85
|
end
|
183
86
|
|
184
87
|
protected
|
@@ -187,30 +90,31 @@ module Mongo::Object
|
|
187
90
|
if class_name = doc[:_class] || doc['_class']
|
188
91
|
klass = constantize class_name
|
189
92
|
|
93
|
+
# Unmarshalling object.
|
190
94
|
if klass.respond_to? :from_mongo
|
191
95
|
obj = klass.from_mongo doc
|
192
96
|
else
|
193
97
|
obj = klass.new
|
194
98
|
parent ||= obj
|
195
99
|
doc.each do |k, v|
|
196
|
-
next if k.to_sym == :_class
|
197
|
-
|
198
100
|
v = _build v, parent
|
199
101
|
obj.instance_variable_set "@#{k}", v
|
200
102
|
end
|
201
103
|
obj
|
202
104
|
end
|
203
105
|
obj._parent = parent if parent
|
204
|
-
|
106
|
+
|
107
|
+
# Firing special after build callback if defined.
|
108
|
+
obj.run_after_callbacks :build, :build if obj.respond_to? :run_after_callbacks
|
109
|
+
|
205
110
|
obj
|
206
111
|
else
|
207
|
-
|
208
|
-
doc.each{|k, v| hash[k] = _build v, parent}
|
209
|
-
hash
|
112
|
+
{}.tap{|h| doc.each{|k, v| h[k] = _build v, parent}}
|
210
113
|
end
|
211
114
|
elsif doc.is_a? Array
|
212
115
|
doc.collect{|v| _build v, parent}
|
213
116
|
else
|
117
|
+
# Simple type.
|
214
118
|
doc
|
215
119
|
end
|
216
120
|
end
|
@@ -224,102 +128,4 @@ module Mongo::Object
|
|
224
128
|
klass
|
225
129
|
end
|
226
130
|
end
|
227
|
-
|
228
|
-
protected
|
229
|
-
def original_children; @_original_children ||= [] end
|
230
|
-
|
231
|
-
def update_original_children!
|
232
|
-
return unless ::Mongo.defaults[:callbacks]
|
233
|
-
|
234
|
-
original_children.clear
|
235
|
-
::Mongo::Object.each_object self do |obj|
|
236
|
-
original_children << obj unless obj.equal?(self)
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def clear_child_objects_cache
|
241
|
-
if instance_variable_get(:@_child_objects_cache)
|
242
|
-
child_objects.each do |group|
|
243
|
-
group.each{|obj| obj.clear_child_objects_cache}
|
244
|
-
end
|
245
|
-
remove_instance_variable :@_child_objects_cache
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
def child_objects
|
250
|
-
unless @_child_objects_cache
|
251
|
-
created_children, updated_children, destroyed_children = [], [], []
|
252
|
-
|
253
|
-
original_children_ids = Set.new; original_children.each{|obj| original_children_ids << obj.object_id}
|
254
|
-
::Mongo::Object.each_object self do |obj|
|
255
|
-
(original_children_ids.include?(obj.object_id) ? updated_children : created_children) << obj unless obj.equal?(self)
|
256
|
-
end
|
257
|
-
|
258
|
-
children_ids = Set.new; ::Mongo::Object.each_object self do |obj|
|
259
|
-
children_ids << obj.object_id unless obj.equal?(self)
|
260
|
-
end
|
261
|
-
destroyed_children = original_children.select{|obj| !children_ids.include?(obj.object_id)}
|
262
|
-
|
263
|
-
@_child_objects_cache = [created_children, updated_children, destroyed_children]
|
264
|
-
end
|
265
|
-
@_child_objects_cache
|
266
|
-
end
|
267
|
-
|
268
|
-
def with_object_callbacks method, options, &block
|
269
|
-
options = ::Mongo::Object.parse_options options
|
270
|
-
|
271
|
-
# validation
|
272
|
-
return false if options[:validate] and !valid?(options.merge(internal: true))
|
273
|
-
|
274
|
-
# before callbacks
|
275
|
-
return false if options[:callbacks] and !run_all_callbacks(:before, method)
|
276
|
-
|
277
|
-
# saving
|
278
|
-
block.call ::Mongo::Object.parse_mongo_options(options)
|
279
|
-
update_original_children!
|
280
|
-
|
281
|
-
# after callbacks
|
282
|
-
run_all_callbacks :after, method if options[:callbacks]
|
283
|
-
|
284
|
-
true
|
285
|
-
ensure
|
286
|
-
clear_child_objects_cache
|
287
|
-
end
|
288
|
-
|
289
|
-
def run_all_callbacks type, method
|
290
|
-
result = if type == :before
|
291
|
-
::Mongo::Object.run_before_callbacks self, method
|
292
|
-
else
|
293
|
-
true
|
294
|
-
end
|
295
|
-
|
296
|
-
result &= if method == :create
|
297
|
-
child_objects.all? do |group|
|
298
|
-
group.all? do |obj|
|
299
|
-
obj.run_all_callbacks type, method
|
300
|
-
end
|
301
|
-
end
|
302
|
-
elsif method == :update
|
303
|
-
created_children, updated_children, destroyed_children = child_objects
|
304
|
-
created_children.all?{|obj| obj.run_all_callbacks type, :create} and
|
305
|
-
updated_children.all?{|obj| obj.run_all_callbacks type, :update} and
|
306
|
-
destroyed_children.all?{|obj| obj.run_all_callbacks type, :destroy}
|
307
|
-
elsif method == :destroy
|
308
|
-
child_objects.all? do |group|
|
309
|
-
group.all? do |obj|
|
310
|
-
obj.run_all_callbacks type, method
|
311
|
-
end
|
312
|
-
end
|
313
|
-
else
|
314
|
-
raise_error "unknown callback method (#{method})!"
|
315
|
-
end
|
316
|
-
|
317
|
-
if type == :after
|
318
|
-
::Mongo::Object.run_after_callbacks self, method
|
319
|
-
else
|
320
|
-
true
|
321
|
-
end
|
322
|
-
|
323
|
-
result
|
324
|
-
end
|
325
131
|
end
|