mongoid 3.0.2 → 3.0.3
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/CHANGELOG.md +16 -1
- data/lib/mongoid/callbacks.rb +32 -0
- data/lib/mongoid/contextual/mongo.rb +4 -18
- data/lib/mongoid/criteria.rb +58 -15
- data/lib/mongoid/extensions/big_decimal.rb +12 -0
- data/lib/mongoid/extensions/object.rb +12 -0
- data/lib/mongoid/persistence/atomic/inc.rb +16 -1
- data/lib/mongoid/persistence/atomic/operation.rb +15 -1
- data/lib/mongoid/relations/auto_save.rb +11 -6
- data/lib/mongoid/relations/embedded/many.rb +10 -0
- data/lib/mongoid/relations/many.rb +0 -10
- data/lib/mongoid/relations/referenced/many.rb +10 -0
- data/lib/mongoid/version.rb +1 -1
- metadata +7 -7
data/CHANGELOG.md
CHANGED
@@ -3,7 +3,22 @@
|
|
3
3
|
For instructions on upgrading to newer versions, visit
|
4
4
|
[mongoid.org](http://mongoid.org/docs/upgrading.html).
|
5
5
|
|
6
|
-
## 3.0.
|
6
|
+
## 3.0.3
|
7
|
+
|
8
|
+
### Resolved Issues
|
9
|
+
|
10
|
+
* \#2259 Ensure subclassed documents can not be pulled from the identity map
|
11
|
+
via an id of another document in the same collection with a parent or
|
12
|
+
sibeling type.
|
13
|
+
|
14
|
+
* \#2254 $inc operations no longer convert all values to floats.
|
15
|
+
|
16
|
+
* \#2252 Don't fire autosave when before callbacks have terminated.
|
17
|
+
|
18
|
+
* \#2248 Improved the performance of `exists?` on criteria and relations.
|
19
|
+
(Jonathan Hyman)
|
20
|
+
|
21
|
+
## 3.0.2
|
7
22
|
|
8
23
|
### Resolved Issues
|
9
24
|
|
data/lib/mongoid/callbacks.rb
CHANGED
@@ -34,6 +34,8 @@ module Mongoid
|
|
34
34
|
define_model_callbacks :initialize, only: :after
|
35
35
|
define_model_callbacks :build, only: :after
|
36
36
|
define_model_callbacks :create, :destroy, :save, :update, :upsert
|
37
|
+
|
38
|
+
attr_accessor :before_callback_halted
|
37
39
|
end
|
38
40
|
|
39
41
|
# Run only the after callbacks for the specific event.
|
@@ -100,6 +102,21 @@ module Mongoid
|
|
100
102
|
|
101
103
|
private
|
102
104
|
|
105
|
+
# We need to hook into this for autosave, since we don't want it firing if
|
106
|
+
# the before callbacks were halted.
|
107
|
+
#
|
108
|
+
# @api private
|
109
|
+
#
|
110
|
+
# @example Was a before callback halted?
|
111
|
+
# document.before_callback_halted?
|
112
|
+
#
|
113
|
+
# @return [ true, false ] If a before callback was halted.
|
114
|
+
#
|
115
|
+
# @since 3.0.3
|
116
|
+
def before_callback_halted?
|
117
|
+
!!@before_callback_halted
|
118
|
+
end
|
119
|
+
|
103
120
|
# Get all the child embedded documents that are flagged as cascadable.
|
104
121
|
#
|
105
122
|
# @example Get all the cascading children.
|
@@ -169,6 +186,21 @@ module Mongoid
|
|
169
186
|
end
|
170
187
|
end
|
171
188
|
|
189
|
+
# We need to hook into this for autosave, since we don't want it firing if
|
190
|
+
# the before callbacks were halted.
|
191
|
+
#
|
192
|
+
# @api private
|
193
|
+
#
|
194
|
+
# @example Hook into the halt.
|
195
|
+
# document.halted_callback_hook(filter)
|
196
|
+
#
|
197
|
+
# @param [ Symbol ] filter The callback that halted.
|
198
|
+
#
|
199
|
+
# @since 3.0.3
|
200
|
+
def halted_callback_hook(filter)
|
201
|
+
@before_callback_halted = true
|
202
|
+
end
|
203
|
+
|
172
204
|
# Run only the callbacks for the target location (before, after, around)
|
173
205
|
# and kind (save, update, create).
|
174
206
|
#
|
@@ -30,7 +30,7 @@ module Mongoid
|
|
30
30
|
#
|
31
31
|
# @since 3.0.0
|
32
32
|
def blank?
|
33
|
-
|
33
|
+
!exists?
|
34
34
|
end
|
35
35
|
alias :empty? :blank?
|
36
36
|
|
@@ -151,7 +151,8 @@ module Mongoid
|
|
151
151
|
#
|
152
152
|
# @since 3.0.0
|
153
153
|
def exists?
|
154
|
-
count
|
154
|
+
# Don't use count here since Mongo does not use counted b-tree indexes
|
155
|
+
!query.dup.select(_id: 1).limit(1).entries.first.nil?
|
155
156
|
end
|
156
157
|
|
157
158
|
# Run an explain on the criteria.
|
@@ -214,7 +215,7 @@ module Mongoid
|
|
214
215
|
def initialize(criteria)
|
215
216
|
@criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
|
216
217
|
@collection = klass.collection
|
217
|
-
|
218
|
+
criteria.send(:merge_type_selection)
|
218
219
|
@query = collection.find(criteria.selector)
|
219
220
|
apply_options
|
220
221
|
end
|
@@ -325,21 +326,6 @@ module Mongoid
|
|
325
326
|
|
326
327
|
private
|
327
328
|
|
328
|
-
# For models where inheritance is at play we need to add the type
|
329
|
-
# selection.
|
330
|
-
#
|
331
|
-
# @example Add the type selection.
|
332
|
-
# context.add_type_selection
|
333
|
-
#
|
334
|
-
# @return [ true, false ] If type selection was added.
|
335
|
-
#
|
336
|
-
# @since 3.0.0
|
337
|
-
def add_type_selection
|
338
|
-
if klass.hereditary? && !criteria.selector.keys.include?(:_type)
|
339
|
-
criteria.selector.merge!(_type: { "$in" => klass._types })
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
329
|
# Apply the field limitations.
|
344
330
|
#
|
345
331
|
# @api private
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -178,18 +178,6 @@ module Mongoid
|
|
178
178
|
multi ? result : result.first
|
179
179
|
end
|
180
180
|
|
181
|
-
# Return true if the criteria has some Document or not.
|
182
|
-
#
|
183
|
-
# @example Are there any documents for the criteria?
|
184
|
-
# criteria.exists?
|
185
|
-
#
|
186
|
-
# @return [ true, false ] If documents match.
|
187
|
-
#
|
188
|
-
# @since 1.0.0
|
189
|
-
def exists?
|
190
|
-
context.count > 0
|
191
|
-
end
|
192
|
-
|
193
181
|
# Extract a single id from the provided criteria. Could be in an $and
|
194
182
|
# query or a straight _id query.
|
195
183
|
#
|
@@ -594,12 +582,11 @@ module Mongoid
|
|
594
582
|
#
|
595
583
|
# @since 1.0.0
|
596
584
|
def initialize_copy(other)
|
597
|
-
@selector = other.selector.dup
|
598
|
-
@options = other.options.dup
|
599
585
|
@inclusions = other.inclusions.dup
|
600
586
|
@scoping_options = other.scoping_options
|
601
587
|
@documents = other.documents.dup
|
602
588
|
@context = nil
|
589
|
+
super
|
603
590
|
end
|
604
591
|
|
605
592
|
# Get documents from the database only.
|
@@ -632,9 +619,10 @@ module Mongoid
|
|
632
619
|
# @since 3.0.0
|
633
620
|
def from_identity_map(ids)
|
634
621
|
result = []
|
622
|
+
selection = selector_with_type_selection
|
635
623
|
ids.reject! do |id|
|
636
624
|
doc = IdentityMap.get(klass, id)
|
637
|
-
doc && doc.matches?(
|
625
|
+
doc && doc.matches?(selection) ? result.push(doc) : false
|
638
626
|
end
|
639
627
|
result
|
640
628
|
end
|
@@ -661,6 +649,19 @@ module Mongoid
|
|
661
649
|
end
|
662
650
|
end
|
663
651
|
|
652
|
+
# For models where inheritance is at play we need to add the type
|
653
|
+
# selection.
|
654
|
+
#
|
655
|
+
# @example Add the type selection.
|
656
|
+
# criteria.merge_type_selection
|
657
|
+
#
|
658
|
+
# @return [ true, false ] If type selection was added.
|
659
|
+
#
|
660
|
+
# @since 3.0.3
|
661
|
+
def merge_type_selection
|
662
|
+
selector.merge!(type_selection) if type_selectable?
|
663
|
+
end
|
664
|
+
|
664
665
|
# Convert all the ids to their proper types.
|
665
666
|
#
|
666
667
|
# @api private
|
@@ -688,5 +689,47 @@ module Mongoid
|
|
688
689
|
def raise_invalid
|
689
690
|
raise Errors::InvalidFind.new
|
690
691
|
end
|
692
|
+
|
693
|
+
# Is the criteria type selectable?
|
694
|
+
#
|
695
|
+
# @api private
|
696
|
+
#
|
697
|
+
# @example If the criteria type selectable?
|
698
|
+
# criteria.type_selectable?
|
699
|
+
#
|
700
|
+
# @return [ true, false ] If type selection should be added.
|
701
|
+
#
|
702
|
+
# @since 3.0.3
|
703
|
+
def type_selectable?
|
704
|
+
klass.hereditary? && !selector.keys.include?(:_type)
|
705
|
+
end
|
706
|
+
|
707
|
+
# Get the selector for type selection.
|
708
|
+
#
|
709
|
+
# @api private
|
710
|
+
#
|
711
|
+
# @example Get a type selection hash.
|
712
|
+
# criteria.type_selection
|
713
|
+
#
|
714
|
+
# @return [ Hash ] The type selection.
|
715
|
+
#
|
716
|
+
# @since 3.0.3
|
717
|
+
def type_selection
|
718
|
+
{ _type: { "$in" => klass._types }}
|
719
|
+
end
|
720
|
+
|
721
|
+
# Get a new selector with type selection in it.
|
722
|
+
#
|
723
|
+
# @api private
|
724
|
+
#
|
725
|
+
# @example Get a selector with type selection.
|
726
|
+
# criteria.selector_with_type_selection
|
727
|
+
#
|
728
|
+
# @return [ Hash ] The selector.
|
729
|
+
#
|
730
|
+
# @since 3.0.3
|
731
|
+
def selector_with_type_selection
|
732
|
+
type_selectable? ? selector.merge(type_selection) : selector
|
733
|
+
end
|
691
734
|
end
|
692
735
|
end
|
@@ -3,6 +3,18 @@ module Mongoid
|
|
3
3
|
module Extensions
|
4
4
|
module BigDecimal
|
5
5
|
|
6
|
+
# Convert the big decimal to an $inc-able value.
|
7
|
+
#
|
8
|
+
# @example Convert the big decimal.
|
9
|
+
# bd.__to_inc__
|
10
|
+
#
|
11
|
+
# @return [ Float ] The big decimal as a float.
|
12
|
+
#
|
13
|
+
# @since 3.0.3
|
14
|
+
def __to_inc__
|
15
|
+
to_f
|
16
|
+
end
|
17
|
+
|
6
18
|
# Turn the object from the ruby type we deal with to a Mongo friendly
|
7
19
|
# type.
|
8
20
|
#
|
@@ -52,6 +52,18 @@ module Mongoid
|
|
52
52
|
self
|
53
53
|
end
|
54
54
|
|
55
|
+
# Conversion of an object to an $inc-able value.
|
56
|
+
#
|
57
|
+
# @example Convert the object.
|
58
|
+
# 1.__to_inc__
|
59
|
+
#
|
60
|
+
# @return [ Object ] The object.
|
61
|
+
#
|
62
|
+
# @since 3.0.3
|
63
|
+
def __to_inc__
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
55
67
|
# Do or do not, there is no try. -- Yoda.
|
56
68
|
#
|
57
69
|
# @example Do or do not.
|
@@ -17,13 +17,28 @@ module Mongoid
|
|
17
17
|
# @since 2.0.0
|
18
18
|
def persist
|
19
19
|
prepare do
|
20
|
-
self.value = value.to_f
|
21
20
|
current = document[field] || 0
|
22
21
|
document[field] = current + value
|
23
22
|
execute("$inc")
|
24
23
|
document[field]
|
25
24
|
end
|
26
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# In case we need to cast going to the database.
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
#
|
33
|
+
# @example Cast the value.
|
34
|
+
# operation.cast_value
|
35
|
+
#
|
36
|
+
# @return [ Integer, Float ] The value casted.
|
37
|
+
#
|
38
|
+
# @since 3.0.3
|
39
|
+
def cast_value
|
40
|
+
value.__to_inc__
|
41
|
+
end
|
27
42
|
end
|
28
43
|
end
|
29
44
|
end
|
@@ -47,7 +47,7 @@ module Mongoid
|
|
47
47
|
#
|
48
48
|
# @since 2.0.0
|
49
49
|
def operation(modifier)
|
50
|
-
{ modifier => { path =>
|
50
|
+
{ modifier => { path => cast_value } }
|
51
51
|
end
|
52
52
|
|
53
53
|
# Get the path to the field that is getting atomically updated.
|
@@ -82,6 +82,20 @@ module Mongoid
|
|
82
82
|
|
83
83
|
private
|
84
84
|
|
85
|
+
# In case we need to cast going to the database.
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
#
|
89
|
+
# @example Cast the value.
|
90
|
+
# operation.cast_value
|
91
|
+
#
|
92
|
+
# @return [ Object ] The value.
|
93
|
+
#
|
94
|
+
# @since 3.0.3
|
95
|
+
def cast_value
|
96
|
+
value
|
97
|
+
end
|
98
|
+
|
85
99
|
# Executes the common functionality between operations.
|
86
100
|
#
|
87
101
|
# @api private
|
@@ -61,14 +61,19 @@ module Mongoid
|
|
61
61
|
if metadata.autosave? && autosavable?(metadata)
|
62
62
|
autosaved_relations.push(metadata.name)
|
63
63
|
set_callback :save, :after, unless: :autosaved? do |document|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
# @todo: Durran: Remove with Rails 4 after callback termination.
|
65
|
+
if before_callback_halted?
|
66
|
+
self.before_callback_halted = false
|
67
|
+
else
|
68
|
+
begin_autosave
|
69
|
+
relation = document.send(metadata.name)
|
70
|
+
if relation
|
71
|
+
(relation.do_or_do_not(:in_memory) || Array.wrap(relation)).each do |doc|
|
72
|
+
doc.save
|
73
|
+
end
|
69
74
|
end
|
75
|
+
exit_autosave
|
70
76
|
end
|
71
|
-
exit_autosave
|
72
77
|
end
|
73
78
|
end
|
74
79
|
end
|
@@ -178,6 +178,16 @@ module Mongoid
|
|
178
178
|
remove_all(conditions, :destroy)
|
179
179
|
end
|
180
180
|
|
181
|
+
# Determine if any documents in this relation exist in the database.
|
182
|
+
#
|
183
|
+
# @example Are there persisted documents?
|
184
|
+
# person.posts.exists?
|
185
|
+
#
|
186
|
+
# @return [ true, false ] True is persisted documents exist, false if not.
|
187
|
+
def exists?
|
188
|
+
count > 0
|
189
|
+
end
|
190
|
+
|
181
191
|
# Finds a document in this association through several different
|
182
192
|
# methods.
|
183
193
|
#
|
@@ -72,16 +72,6 @@ module Mongoid
|
|
72
72
|
doc
|
73
73
|
end
|
74
74
|
|
75
|
-
# Determine if any documents in this relation exist in the database.
|
76
|
-
#
|
77
|
-
# @example Are there persisted documents?
|
78
|
-
# person.posts.exists?
|
79
|
-
#
|
80
|
-
# @return [ true, false ] True is persisted documents exist, false if not.
|
81
|
-
def exists?
|
82
|
-
count > 0
|
83
|
-
end
|
84
|
-
|
85
75
|
# Find the first document given the conditions, or creates a new document
|
86
76
|
# with the conditions that were supplied.
|
87
77
|
#
|
@@ -166,6 +166,16 @@ module Mongoid
|
|
166
166
|
target.each { |doc| yield(doc) if block_given? }
|
167
167
|
end
|
168
168
|
|
169
|
+
# Determine if any documents in this relation exist in the database.
|
170
|
+
#
|
171
|
+
# @example Are there persisted documents?
|
172
|
+
# person.posts.exists?
|
173
|
+
#
|
174
|
+
# @return [ true, false ] True is persisted documents exist, false if not.
|
175
|
+
def exists?
|
176
|
+
criteria.exists?
|
177
|
+
end
|
178
|
+
|
169
179
|
# Find the matchind document on the association, either based on id or
|
170
180
|
# conditions.
|
171
181
|
#
|
data/lib/mongoid/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 1.1
|
53
|
+
version: '1.1'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.1
|
61
|
+
version: '1.1'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: origin
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.0
|
69
|
+
version: '1.0'
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 1.0
|
77
|
+
version: '1.0'
|
78
78
|
description: Mongoid is an ODM (Object Document Mapper) Framework for MongoDB, written
|
79
79
|
in Ruby.
|
80
80
|
email:
|
@@ -354,7 +354,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
354
354
|
version: '0'
|
355
355
|
segments:
|
356
356
|
- 0
|
357
|
-
hash: -
|
357
|
+
hash: -2363016562151284772
|
358
358
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
359
359
|
none: false
|
360
360
|
requirements:
|