mongoid 3.0.0.rc → 3.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/CHANGELOG.md +109 -4
- data/README.md +1 -1
- data/Rakefile +1 -0
- data/lib/config/locales/en.yml +15 -1
- data/lib/mongoid.rb +17 -2
- data/lib/mongoid/atomic.rb +54 -7
- data/lib/mongoid/attributes.rb +1 -1
- data/lib/mongoid/attributes/processing.rb +1 -1
- data/lib/mongoid/callbacks.rb +6 -1
- data/lib/mongoid/components.rb +2 -1
- data/lib/mongoid/config.rb +42 -17
- data/lib/mongoid/config/environment.rb +3 -1
- data/lib/mongoid/contextual/aggregable/memory.rb +21 -10
- data/lib/mongoid/contextual/find_and_modify.rb +14 -12
- data/lib/mongoid/contextual/memory.rb +24 -1
- data/lib/mongoid/contextual/mongo.rb +148 -29
- data/lib/mongoid/copyable.rb +6 -24
- data/lib/mongoid/criteria.rb +116 -34
- data/lib/mongoid/document.rb +7 -7
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/no_metadata.rb +21 -0
- data/lib/mongoid/evolvable.rb +19 -0
- data/lib/mongoid/extensions.rb +1 -1
- data/lib/mongoid/extensions/array.rb +38 -1
- data/lib/mongoid/extensions/big_decimal.rb +1 -1
- data/lib/mongoid/extensions/date_time.rb +6 -1
- data/lib/mongoid/extensions/false_class.rb +12 -0
- data/lib/mongoid/extensions/float.rb +12 -0
- data/lib/mongoid/extensions/hash.rb +33 -1
- data/lib/mongoid/extensions/integer.rb +12 -0
- data/lib/mongoid/extensions/object.rb +51 -1
- data/lib/mongoid/extensions/object_id.rb +2 -1
- data/lib/mongoid/extensions/range.rb +24 -0
- data/lib/mongoid/extensions/string.rb +31 -5
- data/lib/mongoid/extensions/true_class.rb +12 -0
- data/lib/mongoid/fields.rb +20 -21
- data/lib/mongoid/fields/foreign_key.rb +23 -7
- data/lib/mongoid/fields/standard.rb +3 -3
- data/lib/mongoid/finders.rb +3 -7
- data/lib/mongoid/hierarchy.rb +19 -1
- data/lib/mongoid/identity_map.rb +20 -4
- data/lib/mongoid/indexes/validators/options.rb +1 -1
- data/lib/mongoid/multi_parameter_attributes.rb +1 -1
- data/lib/mongoid/paranoia.rb +3 -32
- data/lib/mongoid/persistence.rb +33 -15
- data/lib/mongoid/persistence/atomic/operation.rb +1 -1
- data/lib/mongoid/persistence/operations.rb +16 -0
- data/lib/mongoid/persistence/operations/remove.rb +1 -1
- data/lib/mongoid/persistence/operations/upsert.rb +28 -0
- data/lib/mongoid/persistence/upsertion.rb +30 -0
- data/lib/mongoid/relations.rb +16 -0
- data/lib/mongoid/relations/accessors.rb +1 -1
- data/lib/mongoid/relations/bindings/referenced/in.rb +1 -1
- data/lib/mongoid/relations/builder.rb +1 -1
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/many.rb +1 -1
- data/lib/mongoid/relations/cascading.rb +4 -3
- data/lib/mongoid/relations/constraint.rb +1 -1
- data/lib/mongoid/relations/conversions.rb +1 -1
- data/lib/mongoid/relations/embedded/batchable.rb +3 -2
- data/lib/mongoid/relations/embedded/many.rb +4 -4
- data/lib/mongoid/relations/embedded/one.rb +1 -1
- data/lib/mongoid/relations/metadata.rb +67 -23
- data/lib/mongoid/relations/nested_builder.rb +2 -2
- data/lib/mongoid/relations/proxy.rb +9 -7
- data/lib/mongoid/relations/referenced/many.rb +69 -25
- data/lib/mongoid/relations/referenced/many_to_many.rb +14 -13
- data/lib/mongoid/scoping.rb +0 -17
- data/lib/mongoid/serialization.rb +95 -26
- data/lib/mongoid/sessions.rb +30 -6
- data/lib/mongoid/sessions/factory.rb +2 -0
- data/lib/mongoid/threaded.rb +52 -0
- data/lib/mongoid/timestamps/created.rb +1 -1
- data/lib/mongoid/timestamps/updated.rb +2 -1
- data/lib/mongoid/validations/uniqueness.rb +3 -2
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +8 -0
- data/lib/rails/mongoid.rb +8 -5
- metadata +30 -13
- data/lib/mongoid/collections/retry.rb +0 -58
- data/lib/mongoid/javascript.rb +0 -20
- data/lib/mongoid/javascript/functions.yml +0 -63
@@ -8,11 +8,13 @@ module Mongoid
|
|
8
8
|
|
9
9
|
# Get the name of the environment that we are running under. This first
|
10
10
|
# looks for Rails, then Sinatra, then a RACK_ENV environment variable,
|
11
|
-
# and if none of those are found
|
11
|
+
# and if none of those are found raises an error.
|
12
12
|
#
|
13
13
|
# @example Get the env name.
|
14
14
|
# Environment.env_name
|
15
15
|
#
|
16
|
+
# @raise [ Errors::NoEnvironment ] If no environment was set.
|
17
|
+
#
|
16
18
|
# @return [ String ] The name of the current environment.
|
17
19
|
#
|
18
20
|
# @since 2.3.0
|
@@ -38,11 +38,7 @@ module Mongoid
|
|
38
38
|
#
|
39
39
|
# @since 3.0.0
|
40
40
|
def max(field = nil)
|
41
|
-
|
42
|
-
super()
|
43
|
-
else
|
44
|
-
count > 0 ? max_by { |doc| doc.send(field) }.send(field) : nil
|
45
|
-
end
|
41
|
+
block_given? ? super() : aggregate_by(field, :max_by)
|
46
42
|
end
|
47
43
|
|
48
44
|
# Get the min value of the provided field. If provided a block, will
|
@@ -64,11 +60,7 @@ module Mongoid
|
|
64
60
|
#
|
65
61
|
# @since 3.0.0
|
66
62
|
def min(field = nil)
|
67
|
-
|
68
|
-
super()
|
69
|
-
else
|
70
|
-
count > 0 ? min_by { |doc| doc.send(field) }.send(field) : nil
|
71
|
-
end
|
63
|
+
block_given? ? super() : aggregate_by(field, :min_by)
|
72
64
|
end
|
73
65
|
|
74
66
|
# Get the sum value of the provided field. If provided a block, will
|
@@ -92,6 +84,25 @@ module Mongoid
|
|
92
84
|
count > 0 ? super(0) { |doc| doc.send(field) } : nil
|
93
85
|
end
|
94
86
|
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
# Aggregate by the provided field and method.
|
91
|
+
#
|
92
|
+
# @api private
|
93
|
+
#
|
94
|
+
# @example Aggregate by the field and method.
|
95
|
+
# aggregable.aggregate_by(:name, :min_by)
|
96
|
+
#
|
97
|
+
# @param [ Symbol ] field The field to aggregate on.
|
98
|
+
# @param [ Symbol ] method The method (min_by or max_by).
|
99
|
+
#
|
100
|
+
# @return [ Integer ] The aggregate.
|
101
|
+
#
|
102
|
+
# @since 3.0.0
|
103
|
+
def aggregate_by(field, method)
|
104
|
+
count > 0 ? send(method) { |doc| doc.send(field) }.send(field) : nil
|
105
|
+
end
|
95
106
|
end
|
96
107
|
end
|
97
108
|
end
|
@@ -4,6 +4,12 @@ module Mongoid
|
|
4
4
|
class FindAndModify
|
5
5
|
include Command
|
6
6
|
|
7
|
+
# @attribute [r] criteria The criteria for the context.
|
8
|
+
# @attribute [r] options The command options.
|
9
|
+
# @attribute [r] update The updates.
|
10
|
+
# @attribute [r] query The Moped query.
|
11
|
+
attr_reader :criteria, :options, :update, :query
|
12
|
+
|
7
13
|
# Initialize the find and modify command, used for MongoDB's
|
8
14
|
# $findAndModify.
|
9
15
|
#
|
@@ -16,13 +22,12 @@ module Mongoid
|
|
16
22
|
#
|
17
23
|
# @option options [ true, false ] :new Return the updated document.
|
18
24
|
# @option options [ true, false ] :remove Delete the first document.
|
25
|
+
# @option options [ true, false ] :upsert Create the document if it doesn't exist.
|
19
26
|
#
|
20
27
|
# @since 3.0.0
|
21
28
|
def initialize(criteria, update, options = {})
|
22
|
-
@criteria = criteria
|
23
|
-
|
24
|
-
command[:update] = update unless options[:remove]
|
25
|
-
command.merge!(options)
|
29
|
+
@criteria, @options, @update = criteria, options, update
|
30
|
+
@query = criteria.klass.collection.find(criteria.selector)
|
26
31
|
apply_criteria_options
|
27
32
|
end
|
28
33
|
|
@@ -35,9 +40,7 @@ module Mongoid
|
|
35
40
|
#
|
36
41
|
# @since 3.0.0
|
37
42
|
def result
|
38
|
-
|
39
|
-
session.command(command)["value"]
|
40
|
-
end
|
43
|
+
query.modify(update, options)
|
41
44
|
end
|
42
45
|
|
43
46
|
private
|
@@ -53,12 +56,11 @@ module Mongoid
|
|
53
56
|
#
|
54
57
|
# @since 3.0.0
|
55
58
|
def apply_criteria_options
|
56
|
-
|
57
|
-
|
58
|
-
command[:sort] = sort
|
59
|
+
if spec = criteria.options[:sort]
|
60
|
+
query.sort(spec)
|
59
61
|
end
|
60
|
-
if
|
61
|
-
|
62
|
+
if spec = criteria.options[:fields]
|
63
|
+
query.select(spec)
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -345,6 +345,27 @@ module Mongoid
|
|
345
345
|
end
|
346
346
|
end
|
347
347
|
|
348
|
+
# Compare two values, checking for nil.
|
349
|
+
#
|
350
|
+
# @api private
|
351
|
+
#
|
352
|
+
# @example Compare the two objects.
|
353
|
+
# context.compare(a, b)
|
354
|
+
#
|
355
|
+
# @param [ Object ] a The first object.
|
356
|
+
# @param [ Object ] b The first object.
|
357
|
+
#
|
358
|
+
# @return [ Integer ] The comparison value.
|
359
|
+
#
|
360
|
+
# @since 3.0.0
|
361
|
+
def compare(a, b)
|
362
|
+
case
|
363
|
+
when a.nil? then b.nil? ? 0 : 1
|
364
|
+
when b.nil? then -1
|
365
|
+
else a <=> b
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
348
369
|
# Sort the documents in place.
|
349
370
|
#
|
350
371
|
# @example Sort the documents.
|
@@ -356,7 +377,9 @@ module Mongoid
|
|
356
377
|
def in_place_sort(values)
|
357
378
|
values.each_pair do |field, dir|
|
358
379
|
documents.sort! do |a, b|
|
359
|
-
|
380
|
+
a_value, b_value = a[field], b[field]
|
381
|
+
value = compare(a_value.__sortable__, b_value.__sortable__)
|
382
|
+
dir < 0 ? value * -1 : value
|
360
383
|
end
|
361
384
|
end
|
362
385
|
end
|
@@ -33,6 +33,18 @@ module Mongoid
|
|
33
33
|
end
|
34
34
|
alias :empty? :blank?
|
35
35
|
|
36
|
+
# Is the context cached?
|
37
|
+
#
|
38
|
+
# @example Is the context cached?
|
39
|
+
# context.cached?
|
40
|
+
#
|
41
|
+
# @return [ true, false ] If the context is cached.
|
42
|
+
#
|
43
|
+
# @since 3.0.0
|
44
|
+
def cached?
|
45
|
+
!!@cache
|
46
|
+
end
|
47
|
+
|
36
48
|
# Get the number of documents matching the query.
|
37
49
|
#
|
38
50
|
# @example Get the number of matching documents.
|
@@ -114,25 +126,15 @@ module Mongoid
|
|
114
126
|
# @return [ Enumerator ] The enumerator.
|
115
127
|
#
|
116
128
|
# @since 3.0.0
|
117
|
-
def each
|
129
|
+
def each(&block)
|
118
130
|
if block_given?
|
119
131
|
reset_length
|
120
132
|
selecting do
|
121
|
-
|
122
|
-
|
123
|
-
eager_load(docs)
|
124
|
-
docs.each do |doc|
|
125
|
-
yield doc
|
126
|
-
increment_length
|
127
|
-
end
|
128
|
-
docs
|
129
|
-
else
|
130
|
-
query.each do |doc|
|
131
|
-
yield Factory.from_db(klass, doc)
|
132
|
-
increment_length
|
133
|
-
end
|
134
|
-
self
|
133
|
+
documents_for_iteration.each do |doc|
|
134
|
+
yield_and_increment(doc, &block)
|
135
135
|
end
|
136
|
+
@cache_loaded = true
|
137
|
+
eager_loadable? ? docs : self
|
136
138
|
end
|
137
139
|
else
|
138
140
|
to_enum
|
@@ -174,6 +176,7 @@ module Mongoid
|
|
174
176
|
#
|
175
177
|
# @option options [ true, false ] :new Return the updated document.
|
176
178
|
# @option options [ true, false ] :remove Delete the first document.
|
179
|
+
# @option options [ true, false ] :upsert Create the document if it doesn't exist.
|
177
180
|
#
|
178
181
|
# @return [ Document ] The result of the command.
|
179
182
|
#
|
@@ -207,7 +210,7 @@ module Mongoid
|
|
207
210
|
#
|
208
211
|
# @since 3.0.0
|
209
212
|
def initialize(criteria)
|
210
|
-
@criteria, @klass = criteria, criteria.klass
|
213
|
+
@criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
|
211
214
|
add_type_selection
|
212
215
|
@query = klass.collection.find(criteria.selector)
|
213
216
|
apply_options
|
@@ -304,7 +307,7 @@ module Mongoid
|
|
304
307
|
# Update all the matching documents atomically.
|
305
308
|
#
|
306
309
|
# @example Update all the matching documents.
|
307
|
-
# context.update(name: "Smiths")
|
310
|
+
# context.update({ "$set" => { name: "Smiths" }})
|
308
311
|
#
|
309
312
|
# @param [ Hash ] attributes The new attributes for each document.
|
310
313
|
#
|
@@ -313,7 +316,7 @@ module Mongoid
|
|
313
316
|
# @since 3.0.0
|
314
317
|
def update(attributes = nil)
|
315
318
|
return false unless attributes
|
316
|
-
query.update_all(
|
319
|
+
query.update_all(attributes.__consolidate__)
|
317
320
|
end
|
318
321
|
alias :update_all :update
|
319
322
|
|
@@ -388,6 +391,18 @@ module Mongoid
|
|
388
391
|
end
|
389
392
|
end
|
390
393
|
|
394
|
+
# Apply the hint option
|
395
|
+
#
|
396
|
+
# @example Apply the hint params.
|
397
|
+
# context.apply_hint
|
398
|
+
#
|
399
|
+
# @since 3.0.0
|
400
|
+
def apply_hint
|
401
|
+
if spec = criteria.options[:hint]
|
402
|
+
query.hint(spec)
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
391
406
|
# Map the inverse sort symbols to the correct MongoDB values.
|
392
407
|
#
|
393
408
|
# @example Apply the inverse sorting params.
|
@@ -402,6 +417,77 @@ module Mongoid
|
|
402
417
|
end
|
403
418
|
end
|
404
419
|
|
420
|
+
# Is the cache able to be added to?
|
421
|
+
#
|
422
|
+
# @api private
|
423
|
+
#
|
424
|
+
# @example Is the context cacheable?
|
425
|
+
# context.cacheable?
|
426
|
+
#
|
427
|
+
# @return [ true, false ] If caching, and the cache isn't loaded.
|
428
|
+
#
|
429
|
+
# @since 3.0.0
|
430
|
+
def cacheable?
|
431
|
+
cached? && !cache_loaded?
|
432
|
+
end
|
433
|
+
|
434
|
+
# Is the cache fully loaded? Will be true if caching after one full
|
435
|
+
# iteration.
|
436
|
+
#
|
437
|
+
# @api private
|
438
|
+
#
|
439
|
+
# @example Is the cache loaded?
|
440
|
+
# context.cache_loaded?
|
441
|
+
#
|
442
|
+
# @return [ true, false ] If the cache is loaded.
|
443
|
+
#
|
444
|
+
# @since 3.0.0
|
445
|
+
def cache_loaded?
|
446
|
+
!!@cache_loaded
|
447
|
+
end
|
448
|
+
|
449
|
+
# Get the documents for cached queries.
|
450
|
+
#
|
451
|
+
# @api private
|
452
|
+
#
|
453
|
+
# @example Get the cached documents.
|
454
|
+
# context.documents
|
455
|
+
#
|
456
|
+
# @return [ Array<Document> ] The documents.
|
457
|
+
#
|
458
|
+
# @since 3.0.0
|
459
|
+
def documents
|
460
|
+
@documents ||= []
|
461
|
+
end
|
462
|
+
|
463
|
+
# Get the documents the context should iterate. This follows 3 rules:
|
464
|
+
#
|
465
|
+
# 1. If the query is cached, and we already have documents loaded, use
|
466
|
+
# them.
|
467
|
+
# 2. If we are eager loading, then eager load the documents and use
|
468
|
+
# those.
|
469
|
+
# 3. Use the query.
|
470
|
+
#
|
471
|
+
# @api private
|
472
|
+
#
|
473
|
+
# @example Get the documents for iteration.
|
474
|
+
# context.documents_for_iteration
|
475
|
+
#
|
476
|
+
# @return [ Array<Document>, Moped::Query ] The docs to iterate.
|
477
|
+
#
|
478
|
+
# @since 3.0.0
|
479
|
+
def documents_for_iteration
|
480
|
+
if cached? && !documents.empty?
|
481
|
+
documents
|
482
|
+
elsif eager_loadable?
|
483
|
+
docs = query.map{ |doc| Factory.from_db(klass, doc) }
|
484
|
+
eager_load(docs)
|
485
|
+
docs
|
486
|
+
else
|
487
|
+
query
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
405
491
|
# Eager load the inclusions for the provided documents.
|
406
492
|
#
|
407
493
|
# @example Eager load the inclusions.
|
@@ -414,19 +500,32 @@ module Mongoid
|
|
414
500
|
# @since 3.0.0
|
415
501
|
def eager_load(docs)
|
416
502
|
criteria.inclusions.reject! do |metadata|
|
417
|
-
|
418
|
-
if metadata.stores_foreign_key?
|
419
|
-
child_ids = load_ids(metadata.foreign_key).flatten
|
420
|
-
metadata.eager_load(child_ids)
|
421
|
-
else
|
422
|
-
parent_ids = docs.map(&:id)
|
423
|
-
metadata.eager_load(parent_ids)
|
424
|
-
end
|
425
|
-
end
|
503
|
+
metadata.eager_load(eager_loaded_ids(docs, metadata)) if !docs.empty?
|
426
504
|
end
|
427
505
|
self.eager_loaded = true
|
428
506
|
end
|
429
507
|
|
508
|
+
# Get the ids that to be used to eager load documents.
|
509
|
+
#
|
510
|
+
# @api private
|
511
|
+
#
|
512
|
+
# @example Get the ids.
|
513
|
+
# context.eager_load(docs, metadata)
|
514
|
+
#
|
515
|
+
# @param [ Array<Document> ] docs The pre-loaded documents.
|
516
|
+
# @param [ Metadata ] metadata The relation metadata.
|
517
|
+
#
|
518
|
+
# @return [ Array<Object> ] The ids.
|
519
|
+
#
|
520
|
+
# @since 3.0.0
|
521
|
+
def eager_loaded_ids(docs, metadata)
|
522
|
+
if metadata.stores_foreign_key?
|
523
|
+
load_ids(metadata.foreign_key).flatten
|
524
|
+
else
|
525
|
+
docs.map(&:id)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
430
529
|
# Is this context able to be eager loaded?
|
431
530
|
#
|
432
531
|
# @example Is the context eager loadable?
|
@@ -436,7 +535,7 @@ module Mongoid
|
|
436
535
|
#
|
437
536
|
# @since 3.0.0
|
438
537
|
def eager_loadable?
|
439
|
-
!eager_loaded && criteria.inclusions.
|
538
|
+
!eager_loaded && !criteria.inclusions.empty?
|
440
539
|
end
|
441
540
|
|
442
541
|
# Increment the length of the results.
|
@@ -475,7 +574,7 @@ module Mongoid
|
|
475
574
|
#
|
476
575
|
# @param [ String ] key The id or foriegn key string.
|
477
576
|
#
|
478
|
-
# @return [ Array<String, BSON::ObjectId> ] The ids to load.
|
577
|
+
# @return [ Array<String, Moped::BSON::ObjectId> ] The ids to load.
|
479
578
|
#
|
480
579
|
# @since 3.0.0
|
481
580
|
def load_ids(key)
|
@@ -495,6 +594,7 @@ module Mongoid
|
|
495
594
|
apply_limit
|
496
595
|
apply_skip
|
497
596
|
apply_sorting
|
597
|
+
apply_hint
|
498
598
|
end
|
499
599
|
|
500
600
|
# If we are limiting results, we need to set the field limitations on a
|
@@ -538,6 +638,25 @@ module Mongoid
|
|
538
638
|
doc
|
539
639
|
end
|
540
640
|
end
|
641
|
+
|
642
|
+
# Yield to the document and increment the length.
|
643
|
+
#
|
644
|
+
# @api private
|
645
|
+
#
|
646
|
+
# @example Yield and increment.
|
647
|
+
# context.yield_and_increment(doc) do |doc|
|
648
|
+
# ...
|
649
|
+
# end
|
650
|
+
#
|
651
|
+
# @param [ Document ] document The document to yield to.
|
652
|
+
#
|
653
|
+
# @since 3.0.0
|
654
|
+
def yield_and_increment(document, &block)
|
655
|
+
doc = document.respond_to?(:_id) ? document : Factory.from_db(klass, document)
|
656
|
+
yield(doc)
|
657
|
+
increment_length
|
658
|
+
documents.push(doc) if cacheable?
|
659
|
+
end
|
541
660
|
end
|
542
661
|
end
|
543
662
|
end
|
data/lib/mongoid/copyable.rb
CHANGED
@@ -5,15 +5,6 @@ module Mongoid
|
|
5
5
|
module Copyable
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
-
COPYABLES = [
|
9
|
-
:attributes,
|
10
|
-
:metadata,
|
11
|
-
:changed_attributes,
|
12
|
-
:previous_changes
|
13
|
-
]
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
8
|
# Clone or dup the current +Document+. This will return all attributes with
|
18
9
|
# the exception of the document's id and versions, and will reset all the
|
19
10
|
# instance variables.
|
@@ -23,25 +14,16 @@ module Mongoid
|
|
23
14
|
# @example Clone the document.
|
24
15
|
# document.clone
|
25
16
|
#
|
26
|
-
# @example Dup the document.
|
27
|
-
# document.dup
|
28
|
-
#
|
29
17
|
# @param [ Document ] other The document getting cloned.
|
30
18
|
#
|
31
19
|
# @return [ Document ] The new document.
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
value = other.send(name)
|
37
|
-
instance_variable_set(:"@#{name}", value ? value.dup : nil)
|
38
|
-
end
|
39
|
-
attributes.delete("_id")
|
40
|
-
if attributes.delete("versions")
|
41
|
-
attributes["version"] = 1
|
20
|
+
def clone
|
21
|
+
attrs = as_document.except("_id")
|
22
|
+
if attrs.delete("versions")
|
23
|
+
attrs["version"] = 1
|
42
24
|
end
|
43
|
-
|
44
|
-
apply_defaults
|
25
|
+
self.class.new(attrs)
|
45
26
|
end
|
27
|
+
alias :dup :clone
|
46
28
|
end
|
47
29
|
end
|