mongoid 2.3.1 → 2.3.2
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 +34 -1
- data/lib/mongoid.rb +3 -2
- data/lib/mongoid/atomic.rb +23 -2
- data/lib/mongoid/attributes.rb +0 -21
- data/lib/mongoid/callbacks.rb +9 -1
- data/lib/mongoid/components.rb +2 -0
- data/lib/mongoid/config.rb +4 -2
- data/lib/mongoid/contexts/mongo.rb +19 -8
- data/lib/mongoid/criterion/inclusion.rb +6 -4
- data/lib/mongoid/dirty.rb +1 -0
- data/lib/mongoid/document.rb +1 -25
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +13 -0
- data/lib/mongoid/extensions/object/yoda.rb +1 -0
- data/lib/mongoid/matchers/strategies.rb +6 -1
- data/lib/mongoid/persistence.rb +2 -21
- data/lib/mongoid/railtie.rb +8 -1
- data/lib/mongoid/relations/accessors.rb +7 -5
- data/lib/mongoid/relations/binding.rb +2 -29
- data/lib/mongoid/relations/bindings/embedded/in.rb +4 -4
- data/lib/mongoid/relations/bindings/embedded/many.rb +4 -4
- data/lib/mongoid/relations/bindings/embedded/one.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/in.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/many.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
- data/lib/mongoid/relations/bindings/referenced/one.rb +4 -4
- data/lib/mongoid/relations/builder.rb +18 -4
- data/lib/mongoid/relations/builders.rb +0 -17
- data/lib/mongoid/relations/builders/embedded/in.rb +3 -3
- data/lib/mongoid/relations/builders/embedded/many.rb +4 -4
- data/lib/mongoid/relations/builders/embedded/one.rb +3 -3
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/one.rb +1 -0
- data/lib/mongoid/relations/embedded/in.rb +4 -3
- data/lib/mongoid/relations/embedded/many.rb +6 -5
- data/lib/mongoid/relations/embedded/one.rb +4 -3
- data/lib/mongoid/relations/metadata.rb +20 -5
- data/lib/mongoid/relations/proxy.rb +1 -48
- data/lib/mongoid/relations/referenced/in.rb +4 -3
- data/lib/mongoid/relations/referenced/many.rb +4 -3
- data/lib/mongoid/relations/referenced/many_to_many.rb +5 -4
- data/lib/mongoid/relations/referenced/one.rb +4 -3
- data/lib/mongoid/reloading.rb +91 -0
- data/lib/mongoid/state.rb +15 -22
- data/lib/mongoid/threaded.rb +51 -0
- data/lib/mongoid/threaded/lifecycle.rb +163 -0
- data/lib/mongoid/version.rb +1 -1
- metadata +21 -19
data/CHANGELOG.md
CHANGED
@@ -8,7 +8,40 @@ For instructions on upgrading to newer versions, visit
|
|
8
8
|
* Ranges can now be passed to #where criteria to create a $gte/$lte query under the
|
9
9
|
covers. `Person.where(dob: start_date...end_date)`
|
10
10
|
|
11
|
-
## 2.3.
|
11
|
+
## 2.3.2 \[ In Development \] \[ Branch: 2.3.0-stable \]
|
12
|
+
|
13
|
+
* \#1347 Fix embedded matchers when provided a hash value that does not have a
|
14
|
+
modifier as a key.
|
15
|
+
|
16
|
+
* \#1346 Dup default sorting criteria when calling first/last on a criteria.
|
17
|
+
|
18
|
+
* \#1343 When passing no arguments to `Criteria#all_of` return all documents.
|
19
|
+
(Chris Leishman)
|
20
|
+
|
21
|
+
* \#1339 Ensure destroy callbacks are run on cascadable children when deleting via
|
22
|
+
nested attributes.
|
23
|
+
|
24
|
+
* \#1324 Setting `inverse_of: nil` on a many-to-many referencing the same class
|
25
|
+
returns nil for the inverse foreign key.
|
26
|
+
|
27
|
+
* \#1323 Allow both strings and symbols as ids in the attributes array for
|
28
|
+
nested attributes. (Michael Wood)
|
29
|
+
|
30
|
+
* \#1312 Setting a logger on the config now accepts anything that quacks like a
|
31
|
+
logger.
|
32
|
+
|
33
|
+
* \#1297 Don't hit the database when accessing relations if the base is new.
|
34
|
+
|
35
|
+
* \#1239 Allow appending of referenced relations in create blocks, post default set.
|
36
|
+
|
37
|
+
* \#1236 Ensure all models are loaded in rake tasks, so even in threadsafe mode
|
38
|
+
all indexes can be created.
|
39
|
+
|
40
|
+
* \#736 Calling #reload on embedded documents now works properly.
|
41
|
+
|
42
|
+
### Resolved Issues
|
43
|
+
|
44
|
+
## 2.3.1
|
12
45
|
|
13
46
|
### Resolved Issues
|
14
47
|
|
data/lib/mongoid.rb
CHANGED
@@ -28,10 +28,10 @@ require "active_support/inflector"
|
|
28
28
|
require "active_support/time_with_zone"
|
29
29
|
require "active_model"
|
30
30
|
require "mongo"
|
31
|
-
require "mongoid/errors"
|
32
31
|
require "mongoid/extensions"
|
33
|
-
require "mongoid/
|
32
|
+
require "mongoid/errors"
|
34
33
|
require "mongoid/threaded"
|
34
|
+
require "mongoid/relations"
|
35
35
|
require "mongoid/atomic"
|
36
36
|
require "mongoid/attributes"
|
37
37
|
require "mongoid/callbacks"
|
@@ -64,6 +64,7 @@ require "mongoid/named_scope"
|
|
64
64
|
require "mongoid/nested_attributes"
|
65
65
|
require "mongoid/observer"
|
66
66
|
require "mongoid/persistence"
|
67
|
+
require "mongoid/reloading"
|
67
68
|
require "mongoid/safety"
|
68
69
|
require "mongoid/scope"
|
69
70
|
require "mongoid/serialization"
|
data/lib/mongoid/atomic.rb
CHANGED
@@ -101,7 +101,15 @@ module Mongoid #:nodoc:
|
|
101
101
|
#
|
102
102
|
# @since 2.2.0
|
103
103
|
def atomic_pulls
|
104
|
-
|
104
|
+
delayed_atomic_pulls.inject({}) do |pulls, (name, docs)|
|
105
|
+
pulls.tap do |pull|
|
106
|
+
docs.each do |doc|
|
107
|
+
(pull[doc.atomic_path] ||= []).push(doc.as_document)
|
108
|
+
doc.destroyed = true
|
109
|
+
doc.flagged_for_destroy = false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
105
113
|
end
|
106
114
|
|
107
115
|
# Add the document as an atomic pull.
|
@@ -113,7 +121,8 @@ module Mongoid #:nodoc:
|
|
113
121
|
#
|
114
122
|
# @since 2.2.0
|
115
123
|
def add_atomic_pull(document)
|
116
|
-
|
124
|
+
document.flagged_for_destroy = true
|
125
|
+
(delayed_atomic_pulls[document.metadata.name.to_s] ||= []).push(document)
|
117
126
|
end
|
118
127
|
|
119
128
|
# Get all the push attributes that need to occur.
|
@@ -175,6 +184,18 @@ module Mongoid #:nodoc:
|
|
175
184
|
@delayed_atomic_sets ||= {}
|
176
185
|
end
|
177
186
|
|
187
|
+
# Get a hash of atomic pulls that are pending.
|
188
|
+
#
|
189
|
+
# @example Get the atomic pulls.
|
190
|
+
# document.delayed_atomic_pulls
|
191
|
+
#
|
192
|
+
# @return [ Hash ] name/document pairs.
|
193
|
+
#
|
194
|
+
# @since 2.3.2
|
195
|
+
def delayed_atomic_pulls
|
196
|
+
@delayed_atomic_pulls ||= {}
|
197
|
+
end
|
198
|
+
|
178
199
|
private
|
179
200
|
|
180
201
|
# Get the atomic paths utility for this document.
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -175,27 +175,6 @@ module Mongoid #:nodoc:
|
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
|
-
# Begin the assignment of attributes. While in this block embedded
|
179
|
-
# documents will not autosave themselves in order to allow the document to
|
180
|
-
# be in a valid state.
|
181
|
-
#
|
182
|
-
# @example Execute the assignment.
|
183
|
-
# _assigning do
|
184
|
-
# person.attributes = { :addresses => [ address ] }
|
185
|
-
# end
|
186
|
-
#
|
187
|
-
# @return [ Object ] The yielded value.
|
188
|
-
#
|
189
|
-
# @since 2.2.0
|
190
|
-
def _assigning
|
191
|
-
begin
|
192
|
-
Threaded.begin_assign
|
193
|
-
yield
|
194
|
-
ensure
|
195
|
-
Threaded.exit_assign
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
178
|
# Used for allowing accessor methods for dynamic attributes.
|
200
179
|
#
|
201
180
|
# @param [ String, Symbol ] name The name of the method.
|
data/lib/mongoid/callbacks.rb
CHANGED
@@ -82,6 +82,8 @@ module Mongoid #:nodoc:
|
|
82
82
|
[].tap do |children|
|
83
83
|
relations.each_pair do |name, metadata|
|
84
84
|
next unless metadata.cascading_callbacks?
|
85
|
+
delayed_pulls = delayed_atomic_pulls[name]
|
86
|
+
children.concat(delayed_pulls) if delayed_pulls
|
85
87
|
child = send(name)
|
86
88
|
Array.wrap(child).each do |doc|
|
87
89
|
children.push(doc) if cascadable_child?(kind, doc)
|
@@ -121,7 +123,13 @@ module Mongoid #:nodoc:
|
|
121
123
|
#
|
122
124
|
# @since 2.3.0
|
123
125
|
def child_callback_type(kind, child)
|
124
|
-
kind == :update
|
126
|
+
if kind == :update
|
127
|
+
return :create if child.new_record?
|
128
|
+
return :destroy if child.flagged_for_destroy?
|
129
|
+
kind
|
130
|
+
else
|
131
|
+
kind
|
132
|
+
end
|
125
133
|
end
|
126
134
|
end
|
127
135
|
end
|
data/lib/mongoid/components.rb
CHANGED
@@ -34,10 +34,12 @@ module Mongoid #:nodoc
|
|
34
34
|
include Mongoid::NestedAttributes
|
35
35
|
include Mongoid::Persistence
|
36
36
|
include Mongoid::Relations
|
37
|
+
include Mongoid::Reloading
|
37
38
|
include Mongoid::Safety
|
38
39
|
include Mongoid::Serialization
|
39
40
|
include Mongoid::Sharding
|
40
41
|
include Mongoid::State
|
42
|
+
include Mongoid::Threaded::Lifecycle
|
41
43
|
include Mongoid::Timestamps::Timeless
|
42
44
|
include Mongoid::Validations
|
43
45
|
include Mongoid::Callbacks
|
data/lib/mongoid/config.rb
CHANGED
@@ -166,8 +166,10 @@ module Mongoid #:nodoc
|
|
166
166
|
# @return [ Logger ] The newly set logger.
|
167
167
|
def logger=(logger)
|
168
168
|
case logger
|
169
|
-
|
170
|
-
|
169
|
+
when false, nil then @logger = nil
|
170
|
+
when true then @logger = default_logger
|
171
|
+
else
|
172
|
+
@logger = logger if logger.respond_to?(:info)
|
171
173
|
end
|
172
174
|
end
|
173
175
|
|
@@ -158,10 +158,7 @@ module Mongoid #:nodoc:
|
|
158
158
|
#
|
159
159
|
# @return [ Document ] The first document in the collection.
|
160
160
|
def first
|
161
|
-
|
162
|
-
sorting = opts[:sort] ||= []
|
163
|
-
sorting << [:_id, :asc]
|
164
|
-
attributes = klass.collection.find_one(selector, opts)
|
161
|
+
attributes = klass.collection.find_one(selector, options_with_default_sorting)
|
165
162
|
attributes ? Mongoid::Factory.from_db(klass, attributes) : nil
|
166
163
|
end
|
167
164
|
alias :one :first
|
@@ -225,10 +222,8 @@ module Mongoid #:nodoc:
|
|
225
222
|
#
|
226
223
|
# @return [ Document ] The last document in the collection.
|
227
224
|
def last
|
228
|
-
opts =
|
229
|
-
|
230
|
-
sorting << [:_id, :asc]
|
231
|
-
opts[:sort] = sorting.map{ |option| [ option[0], option[1].invert ] }.uniq
|
225
|
+
opts = options_with_default_sorting
|
226
|
+
opts[:sort] = opts[:sort].map{ |option| [ option[0], option[1].invert ] }.uniq
|
232
227
|
attributes = klass.collection.find_one(selector, opts)
|
233
228
|
attributes ? Mongoid::Factory.from_db(klass, attributes) : nil
|
234
229
|
end
|
@@ -374,6 +369,22 @@ module Mongoid #:nodoc:
|
|
374
369
|
value && value.do_or_do_not(:nan?) ? nil : value
|
375
370
|
end
|
376
371
|
|
372
|
+
# Get the options hash with the default sorting options provided.
|
373
|
+
#
|
374
|
+
# @example Get the options.
|
375
|
+
# criteria.options_with_default_sorting
|
376
|
+
#
|
377
|
+
# @return [ Hash ] The options.
|
378
|
+
#
|
379
|
+
# @since 2.3.2
|
380
|
+
def options_with_default_sorting
|
381
|
+
process_options.tap do |opts|
|
382
|
+
sorting = opts[:sort] ? opts[:sort].dup : []
|
383
|
+
sorting << [:_id, :asc]
|
384
|
+
opts[:sort] = sorting
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
377
388
|
# Filters the field list. If no fields have been supplied, then it will be
|
378
389
|
# empty. If fields have been defined then _type will be included as well.
|
379
390
|
#
|
@@ -34,10 +34,12 @@ module Mongoid #:nodoc:
|
|
34
34
|
# @since 2.3.0
|
35
35
|
def all_of(*args)
|
36
36
|
clone.tap do |crit|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
unless args.empty?
|
38
|
+
criterion = @selector["$and"] || []
|
39
|
+
converted = BSON::ObjectId.convert(klass, args.flatten)
|
40
|
+
expanded = converted.collect { |hash| hash.expand_complex_criteria }
|
41
|
+
crit.selector["$and"] = criterion.concat(expanded)
|
42
|
+
end
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
data/lib/mongoid/dirty.rb
CHANGED
data/lib/mongoid/document.rb
CHANGED
@@ -129,38 +129,14 @@ module Mongoid #:nodoc:
|
|
129
129
|
@attributes ||= {}
|
130
130
|
options ||= {}
|
131
131
|
process(attrs, options[:as] || :default, !options[:without_protection]) do
|
132
|
-
yield self if block_given?
|
133
132
|
identify
|
134
133
|
apply_defaults
|
134
|
+
yield(self) if block_given?
|
135
135
|
end
|
136
136
|
run_callbacks(:initialize) { self }
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
# Reloads the +Document+ attributes from the database. If the document has
|
141
|
-
# not been saved then an error will get raised if the configuration option
|
142
|
-
# was set.
|
143
|
-
#
|
144
|
-
# @example Reload the document.
|
145
|
-
# person.reload
|
146
|
-
#
|
147
|
-
# @raise [ Errors::DocumentNotFound ] If the document was deleted.
|
148
|
-
#
|
149
|
-
# @return [ Document ] The document, reloaded.
|
150
|
-
def reload
|
151
|
-
reloaded = collection.find_one(:_id => id)
|
152
|
-
if Mongoid.raise_not_found_error
|
153
|
-
raise Errors::DocumentNotFound.new(self.class, id) if reloaded.nil?
|
154
|
-
end
|
155
|
-
@attributes = {}.merge(reloaded || {})
|
156
|
-
changed_attributes.clear
|
157
|
-
apply_defaults
|
158
|
-
tap do
|
159
|
-
reload_relations
|
160
|
-
run_callbacks(:initialize)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
140
|
# Return an array with this +Document+ only in it.
|
165
141
|
#
|
166
142
|
# @example Return the document in an array.
|
@@ -26,6 +26,19 @@ module Mongoid #:nodoc:
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
# Get the id attribute from this hash, whether it's prefixed with an
|
31
|
+
# underscore or is a symbol.
|
32
|
+
#
|
33
|
+
# @example Extract the id.
|
34
|
+
# { :_id => 1 }.extract_id
|
35
|
+
#
|
36
|
+
# @return [ Object ] The value of the id.
|
37
|
+
#
|
38
|
+
# @since 2.3.2
|
39
|
+
def extract_id
|
40
|
+
self["id"] || self["_id"] || self[:id] || self[:_id]
|
41
|
+
end
|
29
42
|
end
|
30
43
|
end
|
31
44
|
end
|
@@ -51,7 +51,12 @@ module Mongoid #:nodoc:
|
|
51
51
|
# @since 2.0.0.rc.7
|
52
52
|
def matcher(document, key, value)
|
53
53
|
if value.is_a?(Hash)
|
54
|
-
MATCHERS[value.keys.first]
|
54
|
+
matcher = MATCHERS[value.keys.first]
|
55
|
+
if matcher
|
56
|
+
matcher.new(extract_attribute(document, key))
|
57
|
+
else
|
58
|
+
Default.new(extract_attribute(document, key))
|
59
|
+
end
|
55
60
|
else
|
56
61
|
case key
|
57
62
|
when "$or" then Matchers::Or.new(value, document)
|
data/lib/mongoid/persistence.rb
CHANGED
@@ -168,7 +168,7 @@ module Mongoid #:nodoc:
|
|
168
168
|
#
|
169
169
|
# @return [ Document ] The newly created document.
|
170
170
|
def create(attributes = {}, options = {}, &block)
|
171
|
-
|
171
|
+
_creating do
|
172
172
|
new(attributes, options, &block).tap { |doc| doc.save }
|
173
173
|
end
|
174
174
|
end
|
@@ -187,7 +187,7 @@ module Mongoid #:nodoc:
|
|
187
187
|
#
|
188
188
|
# @return [ Document ] The newly created document.
|
189
189
|
def create!(attributes = {}, options = {}, &block)
|
190
|
-
|
190
|
+
_creating do
|
191
191
|
new(attributes, options, &block).tap do |doc|
|
192
192
|
fail_validate!(doc) if doc.insert.errors.any?
|
193
193
|
fail_callback!(doc, :create!) if doc.new?
|
@@ -259,25 +259,6 @@ module Mongoid #:nodoc:
|
|
259
259
|
def fail_callback!(document, method)
|
260
260
|
raise Errors::Callback.new(document.class, method)
|
261
261
|
end
|
262
|
-
|
263
|
-
private
|
264
|
-
|
265
|
-
# Execute a block in creating mode.
|
266
|
-
#
|
267
|
-
# @example Execute in creating mode.
|
268
|
-
# creating do
|
269
|
-
# relation.push(doc)
|
270
|
-
# end
|
271
|
-
#
|
272
|
-
# @return [ Object ] The return value of the block.
|
273
|
-
#
|
274
|
-
# @since 2.1.0
|
275
|
-
def creating
|
276
|
-
Threaded.begin_create
|
277
|
-
yield
|
278
|
-
ensure
|
279
|
-
Threaded.exit_create
|
280
|
-
end
|
281
262
|
end
|
282
263
|
end
|
283
264
|
end
|
data/lib/mongoid/railtie.rb
CHANGED
@@ -95,7 +95,14 @@ module Rails #:nodoc:
|
|
95
95
|
# environments.
|
96
96
|
initializer "preload all application models" do |app|
|
97
97
|
config.to_prepare do
|
98
|
-
|
98
|
+
if $rails_rake_task
|
99
|
+
# We previously got rid of this, however in the case where
|
100
|
+
# threadsafe! is enabled we must load all models so things like
|
101
|
+
# creating indexes works properly.
|
102
|
+
::Rails::Mongoid.load_models(app)
|
103
|
+
else
|
104
|
+
::Rails::Mongoid.preload_models(app)
|
105
|
+
end
|
99
106
|
end
|
100
107
|
end
|
101
108
|
|
@@ -22,8 +22,8 @@ module Mongoid # :nodoc:
|
|
22
22
|
# @return [ Proxy ] The relation.
|
23
23
|
#
|
24
24
|
# @since 2.0.0.rc.1
|
25
|
-
def build(name, object, metadata
|
26
|
-
relation = create_relation(object, metadata
|
25
|
+
def build(name, object, metadata)
|
26
|
+
relation = create_relation(object, metadata)
|
27
27
|
set_relation(name, relation)
|
28
28
|
end
|
29
29
|
|
@@ -38,9 +38,9 @@ module Mongoid # :nodoc:
|
|
38
38
|
# @return [ Proxy ] The relation.
|
39
39
|
#
|
40
40
|
# @since 2.0.0.rc.1
|
41
|
-
def create_relation(object, metadata
|
41
|
+
def create_relation(object, metadata)
|
42
42
|
type = @attributes[metadata.inverse_type]
|
43
|
-
target = metadata.builder(
|
43
|
+
target = metadata.builder(self, object).build(type)
|
44
44
|
target ? metadata.relation.new(self, target, metadata) : nil
|
45
45
|
end
|
46
46
|
|
@@ -97,7 +97,9 @@ module Mongoid # :nodoc:
|
|
97
97
|
instance_variable_get(variable)
|
98
98
|
else
|
99
99
|
_building do
|
100
|
-
|
100
|
+
_loading do
|
101
|
+
build(name, attributes[metadata.key], metadata)
|
102
|
+
end
|
101
103
|
end
|
102
104
|
end
|
103
105
|
end
|
@@ -4,36 +4,9 @@ module Mongoid # :nodoc:
|
|
4
4
|
|
5
5
|
# Superclass for all objects that bind relations together.
|
6
6
|
class Binding
|
7
|
-
|
8
|
-
|
9
|
-
# Execute a block in binding mode.
|
10
|
-
#
|
11
|
-
# @example Execute in binding mode.
|
12
|
-
# binding do
|
13
|
-
# relation.push(doc)
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# @return [ Object ] The return value of the block.
|
17
|
-
#
|
18
|
-
# @since 2.1.0
|
19
|
-
def binding
|
20
|
-
Threaded.begin_bind
|
21
|
-
yield
|
22
|
-
ensure
|
23
|
-
Threaded.exit_bind
|
24
|
-
end
|
7
|
+
include Threaded::Lifecycle
|
25
8
|
|
26
|
-
|
27
|
-
#
|
28
|
-
# @example Is the thread in binding mode?
|
29
|
-
# binding.binding?
|
30
|
-
#
|
31
|
-
# @return [ true, false ] If the thread is binding.
|
32
|
-
#
|
33
|
-
# @since 2.1.0
|
34
|
-
def binding?
|
35
|
-
Threaded.binding?
|
36
|
-
end
|
9
|
+
attr_reader :base, :target, :metadata
|
37
10
|
|
38
11
|
# Create the new binding.
|
39
12
|
#
|