mongoid 2.3.3 → 2.3.4
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|