mongoid 2.3.3 → 2.3.4
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 +49 -1
- data/lib/config/locales/id.yml +5 -6
- data/lib/mongoid/contexts/mongo.rb +9 -9
- data/lib/mongoid/document.rb +1 -1
- data/lib/mongoid/extensions/object_id/conversions.rb +12 -12
- data/lib/mongoid/factory.rb +5 -1
- data/lib/mongoid/fields/serializable.rb +17 -17
- data/lib/mongoid/fields/serializable/foreign_keys/object.rb +6 -1
- data/lib/mongoid/fields/serializable/time.rb +11 -0
- data/lib/mongoid/fields/serializable/time_with_zone.rb +11 -0
- data/lib/mongoid/finders.rb +1 -1
- data/lib/mongoid/javascript/functions.yml +24 -0
- data/lib/mongoid/persistence/operations/update.rb +9 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
- data/lib/mongoid/relations/builders.rb +22 -4
- data/lib/mongoid/relations/embedded/in.rb +0 -1
- data/lib/mongoid/relations/macros.rb +2 -2
- data/lib/mongoid/relations/referenced/many_to_many.rb +1 -0
- data/lib/mongoid/relations/targets/enumerable.rb +1 -1
- data/lib/mongoid/state.rb +1 -1
- data/lib/mongoid/threaded.rb +54 -5
- data/lib/mongoid/threaded/lifecycle.rb +29 -0
- data/lib/mongoid/timestamps/updated.rb +1 -1
- data/lib/mongoid/validations/uniqueness.rb +10 -3
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +5 -3
- data/lib/rails/mongoid.rb +3 -1
- metadata +20 -20
data/CHANGELOG.md
CHANGED
@@ -8,7 +8,55 @@ 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.4 \[ In Development \] \[ Branch: 2.3.0-stable \]
|
12
|
+
|
13
|
+
* \#1445 Prevent duplicate documents in the loaded array on the target
|
14
|
+
enumerable for relational associations.
|
15
|
+
|
16
|
+
* \#1442 When using create_ methods for has one relations, the appropriate
|
17
|
+
destructive methods now get called when replacing an existing document.
|
18
|
+
|
19
|
+
* \#1431 Enumerable context should add to the loaded array post yield, so
|
20
|
+
that methods like #any? that short circuit based on the value of the block
|
21
|
+
dont falsely have extra documents.
|
22
|
+
|
23
|
+
* \#1418 Documents being loaded from the database for revision purposes
|
24
|
+
no longer get placed in the identity map.
|
25
|
+
|
26
|
+
* \#1399 Allow conversion of strings to integers in foreign keys where the
|
27
|
+
id is defined as an int.
|
28
|
+
|
29
|
+
* \#1397 Don't add default sorting criteria on first if they sort criteria
|
30
|
+
already exists.
|
31
|
+
|
32
|
+
* \#1394 Fix exists? to work when count is greater than 1. (Nick Hoffman)
|
33
|
+
|
34
|
+
* \#1392 Return 0 on aggregation functions where field is nonexistant.
|
35
|
+
|
36
|
+
* \#1391 Uniqueness validation now works properly on embedded documents that are
|
37
|
+
using primary key definitions.
|
38
|
+
|
39
|
+
* \#1390 When _type field is lower case class camelize before constantizing.
|
40
|
+
|
41
|
+
* \#1383 Fix cast on read for serializable fields that are subclassed.
|
42
|
+
|
43
|
+
* \#1357 Delayed atomic sets from update_attributes on embedded documents
|
44
|
+
multiple levels deep now properly persist.
|
45
|
+
|
46
|
+
* \#1326 Ensure base document on HABTM gets its keys saved after saving a newly
|
47
|
+
build child document.
|
48
|
+
|
49
|
+
* \#1301 Don't overwrite base metadata on embedded in relations if already set.
|
50
|
+
|
51
|
+
* \#1221 HABTM with inverse nil is allowed again on embedded documents.
|
52
|
+
|
53
|
+
* \#1208 Don't auto-persist child documents via the setter when setting from
|
54
|
+
an embedded_in.
|
55
|
+
|
56
|
+
* \#791 Root document updates its timestamps when only embedded documents have
|
57
|
+
changed.
|
58
|
+
|
59
|
+
## 2.3.3
|
12
60
|
|
13
61
|
### Resolved Issues
|
14
62
|
|
data/lib/config/locales/id.yml
CHANGED
@@ -5,22 +5,21 @@ id:
|
|
5
5
|
taken:
|
6
6
|
telah digunakan
|
7
7
|
callbacks:
|
8
|
-
"
|
8
|
+
"Memanggil %{method} dalam %{klass} me-return false return dari salah satu callback."
|
9
9
|
document_not_found:
|
10
10
|
Dokumen tidak ditemukan untuk kelas %{klass} dengan id %{identifiers}.
|
11
11
|
eager_load:
|
12
|
-
"Eager loading
|
13
|
-
|
12
|
+
"Eager loading : %{name} is tidak di-support karena merupakan relasi many-to-many
|
13
|
+
atau polymorphic belongs_to."
|
14
14
|
invalid_time:
|
15
|
-
"'%{value}'
|
15
|
+
"'%{value}' bukan merupakan Time yang valid."
|
16
16
|
invalid_database:
|
17
17
|
Database harus Mongo::DB, bukan %{name}.
|
18
18
|
invalid_type:
|
19
19
|
Field didefinisikan sebagai %{klass}, tetapi menerima %{other} dengan
|
20
20
|
value %{value}.
|
21
21
|
invalid_options:
|
22
|
-
"
|
23
|
-
are: %{valid}."
|
22
|
+
"Opsi invalid : %{invalid} untuk relasi : %{name}. Opsi yang valid adalah : %{valid}."
|
24
23
|
unsupported_version:
|
25
24
|
MongoDB %{version} tidak di support, silakan upgrade
|
26
25
|
ke %{mongo_version}.
|
@@ -242,7 +242,7 @@ module Mongoid #:nodoc:
|
|
242
242
|
#
|
243
243
|
# @return [ Numeric ] A numeric max value.
|
244
244
|
def max(field)
|
245
|
-
grouped(:max, field.to_s, Javascript.max)
|
245
|
+
grouped(:max, field.to_s, Javascript.max, Javascript.max_finalize)
|
246
246
|
end
|
247
247
|
|
248
248
|
# Return the min value for a field.
|
@@ -259,7 +259,7 @@ module Mongoid #:nodoc:
|
|
259
259
|
#
|
260
260
|
# @return [ Numeric ] A numeric minimum value.
|
261
261
|
def min(field)
|
262
|
-
grouped(:min, field.to_s, Javascript.min)
|
262
|
+
grouped(:min, field.to_s, Javascript.min, Javascript.min_finalize)
|
263
263
|
end
|
264
264
|
|
265
265
|
# Perform a pull on the matching documents.
|
@@ -306,7 +306,7 @@ module Mongoid #:nodoc:
|
|
306
306
|
#
|
307
307
|
# @return [ Numeric ] A numeric value that is the sum.
|
308
308
|
def sum(field)
|
309
|
-
grouped(:sum, field.to_s, Javascript.sum)
|
309
|
+
grouped(:sum, field.to_s, Javascript.sum, Javascript.sum_finalize)
|
310
310
|
end
|
311
311
|
|
312
312
|
# Very basic update that will perform a simple atomic $set of the
|
@@ -359,14 +359,14 @@ module Mongoid #:nodoc:
|
|
359
359
|
# @param [ String ] reduce The reduce JS function.
|
360
360
|
#
|
361
361
|
# @return [ Numeric ] A numeric result.
|
362
|
-
def grouped(start, field, reduce)
|
362
|
+
def grouped(start, field, reduce, finalize)
|
363
363
|
collection = klass.collection.group(
|
364
364
|
:cond => selector,
|
365
365
|
:initial => { start => "start" },
|
366
|
+
:finalize => finalize,
|
366
367
|
:reduce => reduce.gsub("[field]", field)
|
367
368
|
)
|
368
|
-
|
369
|
-
value && value.do_or_do_not(:nan?) ? nil : value
|
369
|
+
collection.empty? ? nil : collection.first[start.to_s]
|
370
370
|
end
|
371
371
|
|
372
372
|
# Get the options hash with the default sorting options provided.
|
@@ -379,9 +379,9 @@ module Mongoid #:nodoc:
|
|
379
379
|
# @since 2.3.2
|
380
380
|
def options_with_default_sorting
|
381
381
|
process_options.tap do |opts|
|
382
|
-
|
383
|
-
|
384
|
-
|
382
|
+
if opts[:sort].blank?
|
383
|
+
opts[:sort] = [[ :_id, :asc ]]
|
384
|
+
end
|
385
385
|
end
|
386
386
|
end
|
387
387
|
|
data/lib/mongoid/document.rb
CHANGED
@@ -242,7 +242,7 @@ module Mongoid #:nodoc:
|
|
242
242
|
allocate.tap do |doc|
|
243
243
|
doc.instance_variable_set(:@attributes, attributes)
|
244
244
|
doc.send(:apply_defaults)
|
245
|
-
IdentityMap.set(doc)
|
245
|
+
IdentityMap.set(doc) unless _loading_revision?
|
246
246
|
doc.run_callbacks(:initialize) { doc }
|
247
247
|
end
|
248
248
|
end
|
@@ -22,7 +22,7 @@ module Mongoid #:nodoc:
|
|
22
22
|
# BSON::ObjectId.convert(Person, { :_id => "4c52c439931a90ab29000003" })
|
23
23
|
#
|
24
24
|
# @param [ Class ] klass The class to convert the ids for.
|
25
|
-
# @param [ Object, Array, Hash ]
|
25
|
+
# @param [ Object, Array, Hash ] object The object to convert.
|
26
26
|
#
|
27
27
|
# @raise BSON::InvalidObjectId If using object ids and passed bad
|
28
28
|
# strings.
|
@@ -30,28 +30,28 @@ module Mongoid #:nodoc:
|
|
30
30
|
# @return [ BSON::ObjectId, Array, Hash ] The converted object ids.
|
31
31
|
#
|
32
32
|
# @since 2.0.0.rc.7
|
33
|
-
def convert(klass,
|
34
|
-
return
|
35
|
-
case
|
33
|
+
def convert(klass, object, reject_blank = true)
|
34
|
+
return object if object.is_a?(BSON::ObjectId) || !klass.using_object_ids?
|
35
|
+
case object
|
36
36
|
when ::String
|
37
|
-
return nil if
|
38
|
-
if
|
39
|
-
|
37
|
+
return nil if object.blank?
|
38
|
+
if object.unconvertable_to_bson?
|
39
|
+
object
|
40
40
|
else
|
41
|
-
BSON::ObjectId.legal?(
|
41
|
+
BSON::ObjectId.legal?(object) ? BSON::ObjectId.from_string(object) : object
|
42
42
|
end
|
43
43
|
when ::Array
|
44
|
-
|
45
|
-
|
44
|
+
object.delete_if { |arg| arg.blank? } if reject_blank
|
45
|
+
object.replace(object.map { |arg| convert(klass, arg, reject_blank) })
|
46
46
|
when ::Hash
|
47
|
-
|
47
|
+
object.tap do |hash|
|
48
48
|
hash.each_pair do |key, value|
|
49
49
|
next unless klass.object_id_field?(key)
|
50
50
|
hash[key] = convert(klass, value, reject_blank)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
else
|
54
|
-
|
54
|
+
object
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
data/lib/mongoid/factory.rb
CHANGED
@@ -36,7 +36,11 @@ module Mongoid #:nodoc:
|
|
36
36
|
# @return [ Document ] The instantiated document.
|
37
37
|
def from_db(klass, attributes = {})
|
38
38
|
type = attributes["_type"]
|
39
|
-
type.blank?
|
39
|
+
if type.blank?
|
40
|
+
klass.instantiate(attributes)
|
41
|
+
else
|
42
|
+
type.camelize.constantize.instantiate(attributes)
|
43
|
+
end
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
@@ -30,28 +30,13 @@ module Mongoid #:nodoc:
|
|
30
30
|
unless method_defined?(:default)
|
31
31
|
alias :default :default_val
|
32
32
|
end
|
33
|
+
|
34
|
+
class_attribute :cast_on_read
|
33
35
|
end
|
34
36
|
|
35
37
|
# Set readers for the instance variables.
|
36
38
|
attr_accessor :default_val, :label, :localize, :name, :options
|
37
39
|
|
38
|
-
# When reading the field do we need to cast the value? This holds true when
|
39
|
-
# times are stored or for big decimals which are stored as strings.
|
40
|
-
#
|
41
|
-
# @example Typecast on a read?
|
42
|
-
# field.cast_on_read?
|
43
|
-
#
|
44
|
-
# @return [ true, false ] If the field should be cast.
|
45
|
-
#
|
46
|
-
# @since 2.1.0
|
47
|
-
def cast_on_read?
|
48
|
-
return @cast_on_read if defined?(@cast_on_read)
|
49
|
-
@cast_on_read =
|
50
|
-
self.class.public_instance_methods(false).map do |m|
|
51
|
-
m.to_sym
|
52
|
-
end.include?(:deserialize)
|
53
|
-
end
|
54
|
-
|
55
40
|
# Get the constraint from the metadata once.
|
56
41
|
#
|
57
42
|
# @example Get the constraint.
|
@@ -195,6 +180,21 @@ module Mongoid #:nodoc:
|
|
195
180
|
end
|
196
181
|
end
|
197
182
|
end
|
183
|
+
|
184
|
+
private
|
185
|
+
|
186
|
+
# If we define a method called deserialize then we need to cast on
|
187
|
+
# read.
|
188
|
+
#
|
189
|
+
# @example Hook into method added.
|
190
|
+
# method_added(:deserialize)
|
191
|
+
#
|
192
|
+
# @param [ Symbol ] method The method name.
|
193
|
+
#
|
194
|
+
# @since 2.3.4
|
195
|
+
def method_added(method)
|
196
|
+
self.cast_on_read = true if method == :deserialize
|
197
|
+
end
|
198
198
|
end
|
199
199
|
end
|
200
200
|
end
|
@@ -33,7 +33,12 @@ module Mongoid #:nodoc:
|
|
33
33
|
#
|
34
34
|
# @since 2.1.0
|
35
35
|
def serialize(object)
|
36
|
-
|
36
|
+
return nil if object.blank?
|
37
|
+
if object_id_field?
|
38
|
+
constraint.convert(object)
|
39
|
+
else
|
40
|
+
metadata.klass.fields["_id"].serialize(object)
|
41
|
+
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
@@ -6,6 +6,17 @@ module Mongoid #:nodoc:
|
|
6
6
|
class Time
|
7
7
|
include Serializable
|
8
8
|
include Timekeeping
|
9
|
+
|
10
|
+
# When reading the field do we need to cast the value? This holds true when
|
11
|
+
# times are stored or for big decimals which are stored as strings.
|
12
|
+
#
|
13
|
+
# @example Typecast on a read?
|
14
|
+
# field.cast_on_read?
|
15
|
+
#
|
16
|
+
# @return [ true ] Date fields cast on read.
|
17
|
+
#
|
18
|
+
# @since 2.1.0
|
19
|
+
def cast_on_read?; true; end
|
9
20
|
end
|
10
21
|
end
|
11
22
|
end
|
@@ -6,6 +6,17 @@ module Mongoid #:nodoc:
|
|
6
6
|
class TimeWithZone
|
7
7
|
include Serializable
|
8
8
|
include Timekeeping
|
9
|
+
|
10
|
+
# When reading the field do we need to cast the value? This holds true when
|
11
|
+
# times are stored or for big decimals which are stored as strings.
|
12
|
+
#
|
13
|
+
# @example Typecast on a read?
|
14
|
+
# field.cast_on_read?
|
15
|
+
#
|
16
|
+
# @return [ true ] Date fields cast on read.
|
17
|
+
#
|
18
|
+
# @since 2.1.0
|
19
|
+
def cast_on_read?; true; end
|
9
20
|
end
|
10
21
|
end
|
11
22
|
end
|
data/lib/mongoid/finders.rb
CHANGED
@@ -18,6 +18,14 @@ max:
|
|
18
18
|
}
|
19
19
|
}"
|
20
20
|
|
21
|
+
max_finalize:
|
22
|
+
"function(obj) {
|
23
|
+
if (obj.max == 'start' || isNaN(obj.max)) {
|
24
|
+
obj.max = 0;
|
25
|
+
}
|
26
|
+
return obj;
|
27
|
+
}"
|
28
|
+
|
21
29
|
min:
|
22
30
|
"function(obj, prev) {
|
23
31
|
if (obj.[field] && prev.min == 'start') {
|
@@ -28,6 +36,14 @@ min:
|
|
28
36
|
}
|
29
37
|
}"
|
30
38
|
|
39
|
+
min_finalize:
|
40
|
+
"function(obj) {
|
41
|
+
if (obj.min == 'start' || isNaN(obj.min)) {
|
42
|
+
obj.min = 0;
|
43
|
+
}
|
44
|
+
return obj;
|
45
|
+
}"
|
46
|
+
|
31
47
|
sum:
|
32
48
|
"function(obj, prev) {
|
33
49
|
if (prev.sum == 'start') {
|
@@ -37,3 +53,11 @@ sum:
|
|
37
53
|
prev.sum += obj.[field];
|
38
54
|
}
|
39
55
|
}"
|
56
|
+
|
57
|
+
sum_finalize:
|
58
|
+
"function(obj) {
|
59
|
+
if (obj.sum == 'start' || isNaN(obj.sum)) {
|
60
|
+
obj.sum = 0;
|
61
|
+
}
|
62
|
+
return obj;
|
63
|
+
}"
|
@@ -42,6 +42,15 @@ module Mongoid #:nodoc:
|
|
42
42
|
def persist
|
43
43
|
prepare do
|
44
44
|
unless updates.empty?
|
45
|
+
# @todo Durran: This is a temporary fix for #791 until we rewrite
|
46
|
+
# the dirty tracking to properly flag a document as changed if
|
47
|
+
# only embedded documents have changed.
|
48
|
+
if document.respond_to?(:updated_at)
|
49
|
+
if document.timestamping? && !document.updated_at_changed?
|
50
|
+
document.updated_at = Time.now
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
45
54
|
collection.update(selector, updates, options)
|
46
55
|
conflicts.each_pair do |key, value|
|
47
56
|
collection.update(selector, { key => value }, options)
|
@@ -32,6 +32,23 @@ module Mongoid # :nodoc:
|
|
32
32
|
module Builders
|
33
33
|
extend ActiveSupport::Concern
|
34
34
|
|
35
|
+
private
|
36
|
+
|
37
|
+
# Parse out the attributes and the options from the args passed to a
|
38
|
+
# build_ or create_ methods.
|
39
|
+
#
|
40
|
+
# @example Parse the args.
|
41
|
+
# doc.parse_args(:name => "Joe")
|
42
|
+
#
|
43
|
+
# @param [ Array ] args The arguments.
|
44
|
+
#
|
45
|
+
# @return [ Array<Hash> ] The attributes and options.
|
46
|
+
#
|
47
|
+
# @since 2.3.4
|
48
|
+
def parse_args(*args)
|
49
|
+
[ args.first || {}, args.size > 1 ? args[1] : {} ]
|
50
|
+
end
|
51
|
+
|
35
52
|
module ClassMethods #:nodoc:
|
36
53
|
|
37
54
|
# Defines a builder method for an embeds_one relation. This is
|
@@ -48,8 +65,7 @@ module Mongoid # :nodoc:
|
|
48
65
|
def builder(name, metadata)
|
49
66
|
tap do
|
50
67
|
define_method("build_#{name}") do |*args|
|
51
|
-
attributes = args
|
52
|
-
options = args.size > 1 ? args[1] : {}
|
68
|
+
attributes, options = parse_args(*args)
|
53
69
|
document = Factory.build(metadata.klass, attributes, options)
|
54
70
|
_building do
|
55
71
|
send("#{name}=", document)
|
@@ -70,10 +86,12 @@ module Mongoid # :nodoc:
|
|
70
86
|
# @return [ Class ] The class being set up.
|
71
87
|
#
|
72
88
|
# @since 2.0.0.rc.1
|
73
|
-
def creator(name)
|
89
|
+
def creator(name, metadata)
|
74
90
|
tap do
|
75
91
|
define_method("create_#{name}") do |*args|
|
76
|
-
|
92
|
+
attributes, options = parse_args(*args)
|
93
|
+
document = Factory.build(metadata.klass, attributes, options)
|
94
|
+
send("#{name}=", document).tap { |doc| doc.save }
|
77
95
|
end
|
78
96
|
end
|
79
97
|
end
|
@@ -103,7 +103,7 @@ module Mongoid # :nodoc:
|
|
103
103
|
def embeds_one(name, options = {}, &block)
|
104
104
|
characterize(name, Embedded::One, options, &block).tap do |meta|
|
105
105
|
relate(name, meta)
|
106
|
-
builder(name, meta).creator(name)
|
106
|
+
builder(name, meta).creator(name, meta)
|
107
107
|
validates_relation(meta)
|
108
108
|
end
|
109
109
|
end
|
@@ -219,7 +219,7 @@ module Mongoid # :nodoc:
|
|
219
219
|
characterize(name, Referenced::One, options, &block).tap do |meta|
|
220
220
|
relate(name, meta)
|
221
221
|
reference(meta)
|
222
|
-
builder(name, meta).creator(name).autosave(meta)
|
222
|
+
builder(name, meta).creator(name, meta).autosave(meta)
|
223
223
|
validates_relation(meta)
|
224
224
|
end
|
225
225
|
end
|
data/lib/mongoid/state.rb
CHANGED
data/lib/mongoid/threaded.rb
CHANGED
@@ -56,7 +56,7 @@ module Mongoid #:nodoc:
|
|
56
56
|
create_stack.push(true)
|
57
57
|
end
|
58
58
|
|
59
|
-
# Begins a
|
59
|
+
# Begins a loading block.
|
60
60
|
#
|
61
61
|
# @example Begin the load.
|
62
62
|
# Threaded.begin_load
|
@@ -68,6 +68,18 @@ module Mongoid #:nodoc:
|
|
68
68
|
load_stack.push(true)
|
69
69
|
end
|
70
70
|
|
71
|
+
# Begins a loading revision block.
|
72
|
+
#
|
73
|
+
# @example Begin the revision load.
|
74
|
+
# Threaded.begin_load_revision
|
75
|
+
#
|
76
|
+
# @return [ true ] Always true.
|
77
|
+
#
|
78
|
+
# @since 2.3.4
|
79
|
+
def begin_load_revision
|
80
|
+
load_revision_stack.push(true)
|
81
|
+
end
|
82
|
+
|
71
83
|
# Begin validating a document on the current thread.
|
72
84
|
#
|
73
85
|
# @example Begin validation.
|
@@ -128,18 +140,30 @@ module Mongoid #:nodoc:
|
|
128
140
|
!create_stack.empty?
|
129
141
|
end
|
130
142
|
|
131
|
-
# Is the current thread in
|
143
|
+
# Is the current thread in loading mode?
|
132
144
|
#
|
133
|
-
# @example Is the thread in
|
134
|
-
# Threaded.
|
145
|
+
# @example Is the thread in loading mode?
|
146
|
+
# Threaded.loading?
|
135
147
|
#
|
136
|
-
# @return [ true, false ] If the thread is in
|
148
|
+
# @return [ true, false ] If the thread is in loading mode?
|
137
149
|
#
|
138
150
|
# @since 2.3.2
|
139
151
|
def loading?
|
140
152
|
!load_stack.empty?
|
141
153
|
end
|
142
154
|
|
155
|
+
# Is the current thread in revision load mode?
|
156
|
+
#
|
157
|
+
# @example Is the thread in revision load mode?
|
158
|
+
# Threaded.loading_revision?
|
159
|
+
#
|
160
|
+
# @return [ true, false ] If the thread is in revision load mode?
|
161
|
+
#
|
162
|
+
# @since 2.3.4
|
163
|
+
def loading_revision?
|
164
|
+
!load_revision_stack.empty?
|
165
|
+
end
|
166
|
+
|
143
167
|
# Get the assign stack for the current thread. Is simply an array of calls
|
144
168
|
# to Mongoid's assigning method.
|
145
169
|
#
|
@@ -205,6 +229,19 @@ module Mongoid #:nodoc:
|
|
205
229
|
Thread.current[:"[mongoid]:load-stack"] ||= []
|
206
230
|
end
|
207
231
|
|
232
|
+
# Get the revision load stack for the current thread. Is simply an array
|
233
|
+
# of calls to Mongoid's loading_revision method.
|
234
|
+
#
|
235
|
+
# @example Get the revision load stack.
|
236
|
+
# Threaded.load_revision_stack
|
237
|
+
#
|
238
|
+
# @return [ Array ] The array of load revision calls.
|
239
|
+
#
|
240
|
+
# @since 2.3.4
|
241
|
+
def load_revision_stack
|
242
|
+
Thread.current[:"[mongoid]:load-revision-stack"] ||= []
|
243
|
+
end
|
244
|
+
|
208
245
|
# Clear out all the safety options set using the safely proxy.
|
209
246
|
#
|
210
247
|
# @example Clear out the options.
|
@@ -288,6 +325,18 @@ module Mongoid #:nodoc:
|
|
288
325
|
load_stack.pop
|
289
326
|
end
|
290
327
|
|
328
|
+
# Exit the revision loading block.
|
329
|
+
#
|
330
|
+
# @example Exit the revision loading block.
|
331
|
+
# Threaded.exit_load_revision
|
332
|
+
#
|
333
|
+
# @return [ true ] The last element in the stack.
|
334
|
+
#
|
335
|
+
# @since 2.3.4
|
336
|
+
def exit_load_revision
|
337
|
+
load_revision_stack.pop
|
338
|
+
end
|
339
|
+
|
291
340
|
# Exit validating a document on the current thread.
|
292
341
|
#
|
293
342
|
# @example Exit validation.
|
@@ -139,6 +139,23 @@ module Mongoid #:nodoc:
|
|
139
139
|
Threaded.loading?
|
140
140
|
end
|
141
141
|
|
142
|
+
# Execute a block in loading revision mode.
|
143
|
+
#
|
144
|
+
# @example Execute in loading revision mode.
|
145
|
+
# _loading_revision do
|
146
|
+
# load_revision
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# @return [ Object ] The return value of the block.
|
150
|
+
#
|
151
|
+
# @since 2.3.4
|
152
|
+
def _loading_revision
|
153
|
+
Threaded.begin_load_revision
|
154
|
+
yield
|
155
|
+
ensure
|
156
|
+
Threaded.exit_load_revision
|
157
|
+
end
|
158
|
+
|
142
159
|
module ClassMethods #:nodoc:
|
143
160
|
|
144
161
|
# Execute a block in creating mode.
|
@@ -157,6 +174,18 @@ module Mongoid #:nodoc:
|
|
157
174
|
ensure
|
158
175
|
Threaded.exit_create
|
159
176
|
end
|
177
|
+
|
178
|
+
# Is the current thread in loading revision mode?
|
179
|
+
#
|
180
|
+
# @example Is the current thread in loading revision mode?
|
181
|
+
# proxy._loading_revision?
|
182
|
+
#
|
183
|
+
# @return [ true, false ] If the thread is loading a revision.
|
184
|
+
#
|
185
|
+
# @since 2.3.4
|
186
|
+
def _loading_revision?
|
187
|
+
Threaded.loading_revision?
|
188
|
+
end
|
160
189
|
end
|
161
190
|
end
|
162
191
|
end
|
@@ -45,11 +45,17 @@ module Mongoid #:nodoc:
|
|
45
45
|
return if skip_validation?(document)
|
46
46
|
relation = document._parent.send(document.metadata.name)
|
47
47
|
criteria = relation.where(criterion(document, attribute, value))
|
48
|
+
criteria = scope(criteria, document, attribute)
|
49
|
+
if document.primary_key == Array.wrap(attribute)
|
50
|
+
document.errors.add(attribute, :taken) if criteria.count > 1
|
51
|
+
else
|
52
|
+
document.errors.add(attribute, :taken) if criteria.exists?
|
53
|
+
end
|
48
54
|
else
|
49
55
|
criteria = klass.where(criterion(document, attribute, value))
|
56
|
+
criteria = scope(criteria, document, attribute)
|
57
|
+
document.errors.add(attribute, :taken) if criteria.exists?
|
50
58
|
end
|
51
|
-
criteria = scope(criteria, document, attribute)
|
52
|
-
document.errors.add(attribute, :taken) if criteria.exists?
|
53
59
|
end
|
54
60
|
|
55
61
|
protected
|
@@ -80,7 +86,8 @@ module Mongoid #:nodoc:
|
|
80
86
|
# @since 2.3.0
|
81
87
|
def criterion(document, attribute, value)
|
82
88
|
{ attribute => filter(value) }.tap do |selector|
|
83
|
-
if document.persisted? ||
|
89
|
+
if document.persisted? ||
|
90
|
+
(document.embedded? && (document.primary_key != Array.wrap(attribute)))
|
84
91
|
selector.merge!(:_id => { "$ne" => document.id })
|
85
92
|
end
|
86
93
|
end
|
data/lib/mongoid/version.rb
CHANGED
data/lib/mongoid/versioning.rb
CHANGED
@@ -117,9 +117,11 @@ module Mongoid #:nodoc:
|
|
117
117
|
#
|
118
118
|
# @since 2.0.0
|
119
119
|
def previous_revision
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
_loading_revision do
|
121
|
+
self.class.
|
122
|
+
where(:_id => id).
|
123
|
+
any_of({ :version => version }, { :version => nil }).first
|
124
|
+
end
|
123
125
|
end
|
124
126
|
|
125
127
|
# Is the document able to be revised? This is true if the document has
|
data/lib/rails/mongoid.rb
CHANGED
@@ -16,13 +16,15 @@ module Rails #:nodoc:
|
|
16
16
|
# @since 2.1.0
|
17
17
|
def create_indexes(pattern)
|
18
18
|
Dir.glob(pattern).each do |file|
|
19
|
+
logger = Logger.new($stdout)
|
19
20
|
begin
|
20
21
|
model = determine_model(file)
|
21
22
|
if model
|
22
23
|
model.create_indexes
|
23
|
-
|
24
|
+
logger.info("Generated indexes for #{model}")
|
24
25
|
end
|
25
26
|
rescue => e
|
27
|
+
logger.error("ERROR: #{e.message}")
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
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: 2.3.
|
4
|
+
version: 2.3.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
16
|
-
requirement: &
|
16
|
+
requirement: &70174220762600 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.1'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70174220762600
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: tzinfo
|
27
|
-
requirement: &
|
27
|
+
requirement: &70174220760140 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.3.22
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70174220760140
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: mongo
|
38
|
-
requirement: &
|
38
|
+
requirement: &70174220759060 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '1.3'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70174220759060
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rdoc
|
49
|
-
requirement: &
|
49
|
+
requirement: &70174220792380 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 3.5.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70174220792380
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: bson_ext
|
60
|
-
requirement: &
|
60
|
+
requirement: &70174220788760 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '1.3'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70174220788760
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: mocha
|
71
|
-
requirement: &
|
71
|
+
requirement: &70174220786360 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 0.9.12
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70174220786360
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rspec
|
82
|
-
requirement: &
|
82
|
+
requirement: &70174220785700 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '2.6'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70174220785700
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: watchr
|
93
|
-
requirement: &
|
93
|
+
requirement: &70174220855580 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
version: '0.6'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70174220855580
|
102
102
|
description: Mongoid is an ODM (Object Document Mapper) Framework for MongoDB, written
|
103
103
|
in Ruby.
|
104
104
|
email:
|
@@ -393,7 +393,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
393
393
|
version: '0'
|
394
394
|
segments:
|
395
395
|
- 0
|
396
|
-
hash:
|
396
|
+
hash: 4304237674641660259
|
397
397
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
398
398
|
none: false
|
399
399
|
requirements:
|
@@ -402,7 +402,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
402
402
|
version: 1.3.6
|
403
403
|
requirements: []
|
404
404
|
rubyforge_project: mongoid
|
405
|
-
rubygems_version: 1.8.
|
405
|
+
rubygems_version: 1.8.10
|
406
406
|
signing_key:
|
407
407
|
specification_version: 3
|
408
408
|
summary: Elegant Persistance in Ruby for MongoDB.
|