mongoid 3.0.9 → 3.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGELOG.md +94 -6
  2. data/lib/mongoid.rb +1 -1
  3. data/lib/mongoid/atomic.rb +14 -0
  4. data/lib/mongoid/atomic/paths/embedded.rb +4 -2
  5. data/lib/mongoid/callbacks.rb +1 -1
  6. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  7. data/lib/mongoid/contextual/memory.rb +2 -2
  8. data/lib/mongoid/contextual/mongo.rb +1 -0
  9. data/lib/mongoid/criteria.rb +1 -1
  10. data/lib/mongoid/criterion/scoping.rb +1 -1
  11. data/lib/mongoid/dirty.rb +1 -1
  12. data/lib/mongoid/document.rb +7 -4
  13. data/lib/mongoid/errors/document_not_found.rb +1 -0
  14. data/lib/mongoid/errors/mixed_relations.rb +1 -1
  15. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  16. data/lib/mongoid/extensions/date.rb +1 -1
  17. data/lib/mongoid/extensions/date_time.rb +1 -1
  18. data/lib/mongoid/extensions/object.rb +1 -1
  19. data/lib/mongoid/extensions/range.rb +1 -1
  20. data/lib/mongoid/extensions/set.rb +1 -1
  21. data/lib/mongoid/extensions/string.rb +1 -1
  22. data/lib/mongoid/extensions/symbol.rb +1 -1
  23. data/lib/mongoid/extensions/time.rb +1 -1
  24. data/lib/mongoid/extensions/time_with_zone.rb +1 -1
  25. data/lib/mongoid/fields/standard.rb +1 -1
  26. data/lib/mongoid/identity_map.rb +1 -1
  27. data/lib/mongoid/indexes.rb +1 -1
  28. data/lib/mongoid/persistence.rb +1 -1
  29. data/lib/mongoid/persistence/atomic/operation.rb +2 -1
  30. data/lib/mongoid/persistence/modification.rb +1 -0
  31. data/lib/mongoid/relations/accessors.rb +1 -2
  32. data/lib/mongoid/relations/binding.rb +1 -1
  33. data/lib/mongoid/relations/bindings/referenced/in.rb +1 -1
  34. data/lib/mongoid/relations/builders/nested_attributes/many.rb +61 -8
  35. data/lib/mongoid/relations/embedded/many.rb +12 -0
  36. data/lib/mongoid/relations/proxy.rb +6 -9
  37. data/lib/mongoid/relations/referenced/many.rb +1 -0
  38. data/lib/mongoid/relations/targets/enumerable.rb +1 -1
  39. data/lib/mongoid/state.rb +1 -0
  40. data/lib/mongoid/validations/queryable.rb +1 -1
  41. data/lib/mongoid/version.rb +1 -1
  42. data/lib/mongoid/versioning.rb +22 -2
  43. data/lib/rack/mongoid/middleware/identity_map.rb +9 -4
  44. metadata +3 -3
@@ -3,6 +3,70 @@
3
3
  For instructions on upgrading to newer versions, visit
4
4
  [mongoid.org](http://mongoid.org/docs/upgrading.html).
5
5
 
6
+ ## 3.0.10
7
+
8
+ ### Resolved Issues
9
+
10
+ * \#2507 Ensure no extra db hits when eager loading has a mix of parents
11
+ with and without docs. (Douwe Maan)
12
+
13
+ * \#2505 Ensure `update` and `update_all` from criteria properly handle
14
+ aliased fields. (Dmitry Krasnoukhov)
15
+
16
+ * \#2504 `Model#becomes` properly keeps the same id.
17
+
18
+ * \#2498 Criteria now properly pass provided blocks though `method_missing`.
19
+
20
+ * \#2496 Embedded documents that were previously stored without ids now
21
+ properly update and get assigned ids from within Mongoid.
22
+
23
+ * \#2494 All explicit atomic operations now properly respect aliased fields.
24
+
25
+ * \#2493 Use `Class#name` instead of `Class#model_name` when setting
26
+ polymorphic types in case `model_name` has been overridden.
27
+
28
+ * \#2491 Removed unnecessary merge call in cascadable children.
29
+
30
+ * \#2485 Removing indexes now always uses strong consistency.
31
+
32
+ * \#2483 Versioning now handles localized fields. (Lawrence Curtis)
33
+
34
+ * \#2482 Store find parameters in the `DocumentNotFound` error.
35
+
36
+ * \#2481 Map/reduce aggregations now properly handle Mongo's batching of
37
+ reduce jobs in groups of 100 with the state being passed through on the
38
+ count.
39
+
40
+ * \#2476 Handle skip and limit outside of range on embeds_many relations
41
+ gracefully.
42
+
43
+ * \#2474 Correctly detach 1-1 relations when the child is not yet loaded.
44
+ (Kostyantyn Stepanyuk)
45
+
46
+ * \#2451 `relation.deleted` on embedded paranoid documents now works properly
47
+ again.
48
+
49
+ * \#2472 Ensure `update_all` on embedded relations works properly when nothing
50
+ is actually going to be updated.
51
+
52
+ * \#2469 Nullified documents on relations are now able to be re-added with the
53
+ same in memory instance.
54
+
55
+ * \#2454 `Model#as_document` properly allows changes from having a relation to
56
+ the relation being removed. (James Almond)
57
+
58
+ * \#2445 Mongoid middleware now properly supports both normal and streamed
59
+ responses and properly clears the identity map for either.
60
+
61
+ * \#2367 Embedded documents that are to be deleted via nested attributes no
62
+ longer become immediately removed from the relation in case the parent
63
+ validation fails. Instead, they get flagged for destruction and then the
64
+ removal occurs upon the parent passing validation and going to persist.
65
+
66
+ Note this is a behaviour change, but since the API does not change and
67
+ the previous behaviour was incorrect and did not match AR this was able
68
+ to go into a point release.
69
+
6
70
  ## 3.0.9
7
71
 
8
72
  ### Resolved Issues
@@ -470,7 +534,7 @@ For instructions on upgrading to newer versions, visit
470
534
  Enumerable, or included gems that inject methods into these
471
535
  or Mongoid internals.
472
536
 
473
- * \#1753/#1649 A setter and getter for has_many relations to set it's
537
+ * \#1753/#1649 A setter and getter for has_many relations to set its
474
538
  children is now provided. (Piotr Jakubowski)
475
539
 
476
540
  class Album
@@ -696,7 +760,7 @@ For instructions on upgrading to newer versions, visit
696
760
  band.with(database: "secondary).save!
697
761
  Band.with(collection: "artists").where(name: "Depeche Mode")
698
762
 
699
- * \#1291 You can now configure on a per-model basis where it's documents are
763
+ * \#1291 You can now configure on a per-model basis where its documents are
700
764
  stored with the new and improved `store_in` macro.
701
765
 
702
766
  class Band
@@ -813,7 +877,7 @@ For instructions on upgrading to newer versions, visit
813
877
  index({ name: 1 }, { unique: true, background: true })
814
878
  end
815
879
 
816
- Geospacial indexing needs "2d" as it's direction.
880
+ Geospacial indexing needs "2d" as its direction.
817
881
 
818
882
  class Venue
819
883
  include Mongoid::Document
@@ -980,11 +1044,11 @@ For instructions on upgrading to newer versions, visit
980
1044
  If the id is set, but the document for it has not been persisted, accessing
981
1045
  the relation will return empty results.
982
1046
 
983
- If the id is set and it's document is persisted, accessing the relation
1047
+ If the id is set and its document is persisted, accessing the relation
984
1048
  will return the document.
985
1049
 
986
1050
  If the id is set, but the base document is not saved afterwards, then
987
- reloading will return the document to it's original state.
1051
+ reloading will return the document to its original state.
988
1052
 
989
1053
  * \#1093 Field serialization strategies have changed on Array, Hash, Integer
990
1054
  and Boolean to be more consistent and match AR where appropriate.
@@ -1142,7 +1206,31 @@ For instructions on upgrading to newer versions, visit
1142
1206
  * \#685 Attempting to use versioning with embedded documents will now
1143
1207
  raise a proper error alerting the developer this is not allowed.
1144
1208
 
1145
- ## 2.4.12 (branch: 2.4.0-stable)
1209
+ ## 2.5.2 (branch: 2.5.0-stable)
1210
+
1211
+ ### Resolved Issues
1212
+
1213
+ * \#2502 Fixed cache key to properly handle when the document does not
1214
+ include `Mongoid::Timestamps::Updated`. (Arthur Nogueira Neves)
1215
+
1216
+ ## 2.5.1
1217
+
1218
+ ### Resolved Issues
1219
+
1220
+ * \#2492 Backport cascading callbacks performance and memory fixes from
1221
+ 3.0.0-stable.
1222
+
1223
+ * \#2464 Backport the nested attributes fix for keeping many relations in
1224
+ memory when updating attributes. (Chris Thompson)
1225
+
1226
+ ## 2.5.0
1227
+
1228
+ ### New Features
1229
+
1230
+ * This is a release to support the 1.7.0 and higher Mongo and BSON gems and
1231
+ resolves issues that kept the 2.4.x series locked below 1.6.2
1232
+
1233
+ ## 2.4.12
1146
1234
 
1147
1235
  ### Resolved Issues
1148
1236
 
@@ -105,7 +105,7 @@ module Mongoid
105
105
  # config.use(name: "mongoid_test", host: "localhost", port: 27017)
106
106
  # end
107
107
  #
108
- # @return [ Config ] The configuration obejct.
108
+ # @return [ Config ] The configuration object.
109
109
  #
110
110
  # @since 1.0.0
111
111
  def configure
@@ -114,6 +114,7 @@ module Mongoid
114
114
  #
115
115
  # @since 2.1.0
116
116
  def atomic_updates
117
+ process_flagged_destroys
117
118
  mods = Modifiers.new
118
119
  generate_atomic_updates(mods, self)
119
120
  _children.each do |child|
@@ -302,6 +303,19 @@ module Mongoid
302
303
  atomic_path
303
304
  end
304
305
 
306
+ def flagged_destroys
307
+ @flagged_destroys ||= []
308
+ end
309
+
310
+ def process_flagged_destroys
311
+ _assigning do
312
+ flagged_destroys.each do |block|
313
+ block.call
314
+ end
315
+ end
316
+ flagged_destroys.clear
317
+ end
318
+
305
319
  private
306
320
 
307
321
  # Get the atomic paths utility for this document.
@@ -33,8 +33,10 @@ module Mongoid
33
33
  #
34
34
  # @since 2.1.0
35
35
  def selector
36
- parent.atomic_selector.
37
- merge!({ "#{path}._id" => document._id }).merge!(document.shard_key_selector)
36
+ parent.atomic_selector
37
+ # @todo: Durran: Bring this back once MongoDB, if ever, goes to fix
38
+ # this issue: https://jira.mongodb.org/browse/SERVER-831
39
+ # merge!({ "#{path}._id" => document._id }).merge!(document.shard_key_selector)
38
40
  end
39
41
  end
40
42
  end
@@ -153,7 +153,7 @@ module Mongoid
153
153
  Array.wrap(relation).each do |child|
154
154
  next if children.include?(child)
155
155
  children.add(child) if cascadable_child?(kind, child)
156
- children.merge(child.send(:cascadable_children, kind, children))
156
+ child.send(:cascadable_children, kind, children)
157
157
  end
158
158
  end
159
159
  end
@@ -172,7 +172,7 @@ module Mongoid
172
172
  if (agg.min == null || val.max < agg.min) agg.min = val.max;
173
173
  agg.sum += val.sum;
174
174
  }
175
- agg.count += 1;
175
+ agg.count += val.count;
176
176
  });
177
177
  return agg;
178
178
  }}
@@ -117,7 +117,7 @@ module Mongoid
117
117
  # @since 3.0.0
118
118
  def each
119
119
  if block_given?
120
- documents[skipping || 0, limiting || documents.length].each do |doc|
120
+ (documents[skipping || 0, limiting || documents.length] || []).each do |doc|
121
121
  yield doc
122
122
  end
123
123
  else
@@ -286,7 +286,7 @@ module Mongoid
286
286
  docs.each do |doc|
287
287
  @selector ||= root.atomic_selector
288
288
  doc.write_attributes(attributes)
289
- updates["$set"].merge!(doc.atomic_updates["$set"])
289
+ updates["$set"].merge!(doc.atomic_updates["$set"] || {})
290
290
  doc.move_changes
291
291
  end
292
292
  collection.find(selector).update(updates)
@@ -352,6 +352,7 @@ module Mongoid
352
352
  # @since 3.0.4
353
353
  def update_documents(attributes, method = :update)
354
354
  return false unless attributes
355
+ attributes = Hash[attributes.map { |k, v| [klass.database_field_name(k.to_s), v] }]
355
356
  query.send(method, attributes.__consolidate__)
356
357
  end
357
358
 
@@ -668,7 +668,7 @@ module Mongoid
668
668
  klass.send(name, *args, &block)
669
669
  end
670
670
  else
671
- return entries.send(name, *args)
671
+ return entries.send(name, *args, &block)
672
672
  end
673
673
  end
674
674
 
@@ -44,7 +44,7 @@ module Mongoid
44
44
  self
45
45
  end
46
46
 
47
- # Forces the criteria to be scoped, unless it's inside an unscoped block.
47
+ # Forces the criteria to be scoped, unless its inside an unscoped block.
48
48
  #
49
49
  # @example Force the criteria to be scoped.
50
50
  # criteria.scoped(skip: 10)
@@ -228,7 +228,7 @@ module Mongoid
228
228
  end
229
229
  end
230
230
 
231
- # Set the attribute back to it's old value.
231
+ # Set the attribute back to its old value.
232
232
  #
233
233
  # @example Reset the attribute.
234
234
  # model.reset_attribute!("name")
@@ -108,7 +108,7 @@ module Mongoid
108
108
  identity.hash
109
109
  end
110
110
 
111
- # A Document's is identified absolutely by it's class and database id:
111
+ # A Document's is identified absolutely by its class and database id:
112
112
  #
113
113
  # Person.first.identity #=> [Person, Moped::BSON::ObjectId('4f775130a04745933a000003')]
114
114
  #
@@ -191,8 +191,10 @@ module Mongoid
191
191
  return attributes if frozen?
192
192
  embedded_relations.each_pair do |name, meta|
193
193
  without_autobuild do
194
- relation = send(name)
195
- attributes[meta.store_as] = relation.as_document unless relation.blank?
194
+ relation, stored = send(name), meta.store_as
195
+ if attributes.has_key?(stored) || !relation.blank?
196
+ attributes[stored] = relation.as_document
197
+ end
196
198
  end
197
199
  end
198
200
  attributes
@@ -216,6 +218,7 @@ module Mongoid
216
218
  raise ArgumentError, "A class which includes Mongoid::Document is expected"
217
219
  end
218
220
  became = klass.new(as_document.__deep_copy__)
221
+ became.id = id
219
222
  became.instance_variable_set(:@changed_attributes, changed_attributes)
220
223
  became.instance_variable_set(:@errors, errors)
221
224
  became.instance_variable_set(:@new_record, new_record?)
@@ -241,7 +244,7 @@ module Mongoid
241
244
  # @since 2.4.0
242
245
  def cache_key
243
246
  return "#{model_key}/new" if new_record?
244
- return "#{model_key}/#{id}-#{updated_at.utc.to_s(:number)}" if updated_at
247
+ return "#{model_key}/#{id}-#{updated_at.utc.to_s(:number)}" unless self[:updated_at].nil?
245
248
  "#{model_key}/#{id}"
246
249
  end
247
250
 
@@ -24,6 +24,7 @@ module Mongoid
24
24
  if !unmatched && !params.is_a?(Hash)
25
25
  raise ArgumentError, 'please also supply the unmatched ids'
26
26
  end
27
+ @params = params
27
28
  super(
28
29
  compose_message(
29
30
  message_key(params),
@@ -3,7 +3,7 @@ module Mongoid
3
3
  module Errors
4
4
 
5
5
  # This error is raised when trying to reference an embedded document from
6
- # a document in another collection that is not it's parent.
6
+ # a document in another collection that is not its parent.
7
7
  #
8
8
  # @example An illegal reference to an embedded document.
9
9
  # class Post
@@ -30,7 +30,7 @@ module Mongoid
30
30
 
31
31
  module ClassMethods
32
32
 
33
- # Convert the object from it's mongo friendly ruby type to this type.
33
+ # Convert the object from its mongo friendly ruby type to this type.
34
34
  #
35
35
  # @example Demongoize the object.
36
36
  # Object.demongoize(object)
@@ -30,7 +30,7 @@ module Mongoid
30
30
 
31
31
  module ClassMethods
32
32
 
33
- # Convert the object from it's mongo friendly ruby type to this type.
33
+ # Convert the object from its mongo friendly ruby type to this type.
34
34
  #
35
35
  # @example Demongoize the object.
36
36
  # Date.demongoize(object)
@@ -36,7 +36,7 @@ module Mongoid
36
36
 
37
37
  module ClassMethods
38
38
 
39
- # Convert the object from it's mongo friendly ruby type to this type.
39
+ # Convert the object from its mongo friendly ruby type to this type.
40
40
  #
41
41
  # @example Demongoize the object.
42
42
  # DateTime.demongoize(object)
@@ -213,7 +213,7 @@ module Mongoid
213
213
  constraint.convert(object)
214
214
  end
215
215
 
216
- # Convert the object from it's mongo friendly ruby type to this type.
216
+ # Convert the object from its mongo friendly ruby type to this type.
217
217
  #
218
218
  # @example Demongoize the object.
219
219
  # Object.demongoize(object)
@@ -42,7 +42,7 @@ module Mongoid
42
42
 
43
43
  module ClassMethods
44
44
 
45
- # Convert the object from it's mongo friendly ruby type to this type.
45
+ # Convert the object from its mongo friendly ruby type to this type.
46
46
  #
47
47
  # @example Demongoize the object.
48
48
  # Range.demongoize({ "min" => 1, "max" => 5 })
@@ -18,7 +18,7 @@ module Mongoid
18
18
 
19
19
  module ClassMethods
20
20
 
21
- # Convert the object from it's mongo friendly ruby type to this type.
21
+ # Convert the object from its mongo friendly ruby type to this type.
22
22
  #
23
23
  # @example Demongoize the object.
24
24
  # Set.demongoize({ "min" => 1, "max" => 5 })
@@ -150,7 +150,7 @@ module Mongoid
150
150
 
151
151
  module ClassMethods
152
152
 
153
- # Convert the object from it's mongo friendly ruby type to this type.
153
+ # Convert the object from its mongo friendly ruby type to this type.
154
154
  #
155
155
  # @example Demongoize the object.
156
156
  # String.demongoize(object)
@@ -17,7 +17,7 @@ module Mongoid
17
17
 
18
18
  module ClassMethods
19
19
 
20
- # Convert the object from it's mongo friendly ruby type to this type.
20
+ # Convert the object from its mongo friendly ruby type to this type.
21
21
  #
22
22
  # @example Demongoize the object.
23
23
  # Symbol.demongoize(object)
@@ -31,7 +31,7 @@ module Mongoid
31
31
  Mongoid.use_activesupport_time_zone? ? (::Time.zone || ::Time) : ::Time
32
32
  end
33
33
 
34
- # Convert the object from it's mongo friendly ruby type to this type.
34
+ # Convert the object from its mongo friendly ruby type to this type.
35
35
  #
36
36
  # @example Demongoize the object.
37
37
  # Time.demongoize(object)
@@ -18,7 +18,7 @@ module Mongoid
18
18
 
19
19
  module ClassMethods
20
20
 
21
- # Convert the object from it's mongo friendly ruby type to this type.
21
+ # Convert the object from its mongo friendly ruby type to this type.
22
22
  #
23
23
  # @example Demongoize the object.
24
24
  # TimeWithZone.demongoize(object)
@@ -124,7 +124,7 @@ module Mongoid
124
124
  @object_id_field ||= (type == Moped::BSON::ObjectId)
125
125
  end
126
126
 
127
- # Does the field pre-process it's default value?
127
+ # Does the field pre-process its default value?
128
128
  #
129
129
  # @example Does the field pre-process the default?
130
130
  # field.pre_processed?
@@ -76,7 +76,7 @@ module Mongoid
76
76
  end
77
77
  end
78
78
 
79
- # Puts a document in the identity map, accessed by it's id.
79
+ # Puts a document in the identity map, accessed by its id.
80
80
  #
81
81
  # @example Put the document in the map.
82
82
  # identity_map.set(document)
@@ -37,7 +37,7 @@ module Mongoid
37
37
  #
38
38
  # @since 3.0.0
39
39
  def remove_indexes
40
- collection.indexes.each do |spec|
40
+ with(consistency: :strong).collection.indexes.each do |spec|
41
41
  next if spec["name"] == "_id_"
42
42
  collection.indexes.drop(spec["key"])
43
43
  end and true
@@ -99,7 +99,7 @@ module Mongoid
99
99
  return true
100
100
  end
101
101
 
102
- # Touch the document, in effect updating it's updated_at timestamp and
102
+ # Touch the document, in effect updating its updated_at timestamp and
103
103
  # optionally the provided field to the current time. If any belongs_to
104
104
  # relations exist with a touch option, they will be updated as well.
105
105
  #
@@ -32,7 +32,8 @@ module Mongoid
32
32
  #
33
33
  # @since 2.0.0
34
34
  def initialize(document, field, value, options = {})
35
- @document, @field, @value = document, field.to_s, value
35
+ @document, @field, @value =
36
+ document, document.database_field_name(field.to_s), value
36
37
  @options = options
37
38
  end
38
39
 
@@ -20,6 +20,7 @@ module Mongoid
20
20
  # @since 2.1.0
21
21
  def prepare(&block)
22
22
  return false if validating? && document.invalid?(:update)
23
+ document.process_flagged_destroys
23
24
  result = document.run_callbacks(:save) do
24
25
  document.run_callbacks(:update) do
25
26
  yield(document); true
@@ -201,8 +201,7 @@ module Mongoid
201
201
  def setter(name, metadata)
202
202
  re_define_method("#{name}=") do |object|
203
203
  without_autobuild do
204
- if relation_exists?(name) || metadata.many? ||
205
- (object.blank? && send(name))
204
+ if metadata.many? || send(name)
206
205
  set_relation(name, send(name).substitute(object.substitutable))
207
206
  else
208
207
  __build__(name, object.substitutable, metadata)
@@ -191,7 +191,7 @@ module Mongoid
191
191
  def bind_from_relational_parent(doc)
192
192
  check_inverse!(doc)
193
193
  bind_foreign_key(doc, base.id)
194
- bind_polymorphic_type(doc, base.class.model_name)
194
+ bind_polymorphic_type(doc, base.class.name)
195
195
  bind_inverse(doc, base)
196
196
  bind_inverse_of_field(doc, metadata.name)
197
197
  end
@@ -22,7 +22,7 @@ module Mongoid
22
22
  binding do
23
23
  check_inverses!(target)
24
24
  bind_foreign_key(base, target.id)
25
- bind_polymorphic_inverse_type(base, target.class.model_name)
25
+ bind_polymorphic_inverse_type(base, target.class.name)
26
26
  if inverse = metadata.inverse(target)
27
27
  if set_base_metadata
28
28
  bind_inverse_of_field(base, base.metadata_name)
@@ -103,20 +103,73 @@ module Mongoid
103
103
  converted = first ? convert_id(first.class, id) : id
104
104
  doc = existing.find(converted)
105
105
  if destroyable?(attrs)
106
- existing.delete(doc)
107
- doc.destroy unless doc.embedded? || doc.destroyed?
106
+ destroy(parent, existing, doc)
108
107
  else
109
- attrs.delete_id
110
- if metadata.embedded?
111
- doc.assign_attributes(attrs, options)
112
- else
113
- doc.update_attributes(attrs, options)
114
- end
108
+ update_document(doc, attrs, options)
115
109
  end
116
110
  else
117
111
  existing.push(Factory.build(metadata.klass, attrs, options)) unless destroyable?(attrs)
118
112
  end
119
113
  end
114
+
115
+ # Destroy the child document, needs to do some checking for embedded
116
+ # relations and delay the destroy in case parent validation fails.
117
+ #
118
+ # @api private
119
+ #
120
+ # @example Destroy the child.
121
+ # builder.destroy(parent, relation, doc)
122
+ #
123
+ # @param [ Document ] parent The parent document.
124
+ # @param [ Proxy ] relation The relation proxy.
125
+ # @param [ Document ] doc The doc to destroy.
126
+ #
127
+ # @since 3.0.10
128
+ def destroy(parent, relation, doc)
129
+ doc.flagged_for_destroy = true
130
+ if !doc.embedded? || parent.new_record? || doc.paranoid?
131
+ destroy_document(relation, doc)
132
+ else
133
+ parent.flagged_destroys.push(->{ destroy_document(relation, doc) })
134
+ end
135
+ end
136
+
137
+ # Destroy the document.
138
+ #
139
+ # @api private
140
+ #
141
+ # @example Destroy the document.
142
+ # builder.destroy_document(relation, doc)
143
+ #
144
+ # @param [ Proxy ] relation The relation proxy.
145
+ # @param [ Document ] doc The document to delete.
146
+ #
147
+ # @since 3.0.10
148
+ def destroy_document(relation, doc)
149
+ relation.delete(doc)
150
+ doc.destroy unless doc.embedded? || doc.destroyed?
151
+ end
152
+
153
+ # Update the document.
154
+ #
155
+ # @api private
156
+ #
157
+ # @example Update the document.
158
+ # builder.update_document(doc, {}, options)
159
+ #
160
+ # @param [ Document ] doc The document to update.
161
+ # @param [ Hash ] attrs The attributes.
162
+ # @param [ Hash ] options The options.
163
+ #
164
+ # @since 3.0.10
165
+ def update_document(doc, attrs, options)
166
+ attrs.delete_id
167
+ if metadata.embedded?
168
+ doc.assign_attributes(attrs, options)
169
+ else
170
+ doc.update_attributes(attrs, options)
171
+ end
172
+ end
120
173
  end
121
174
  end
122
175
  end
@@ -148,6 +148,18 @@ module Mongoid
148
148
  doc
149
149
  end
150
150
 
151
+ # For use only with Mongoid::Paranoia - will be removed in 4.0.
152
+ #
153
+ # @example Get the deleted documents from the relation.
154
+ # person.paranoid_phones.deleted
155
+ #
156
+ # @return [ Criteria ] The deleted documents.
157
+ #
158
+ # @since 3.0.10
159
+ def deleted
160
+ unscoped.deleted
161
+ end
162
+
151
163
  # Delete all the documents in the association without running callbacks.
152
164
  #
153
165
  # @example Delete all documents from the relation.
@@ -177,15 +177,12 @@ module Mongoid
177
177
  def eager_load_ids(metadata, ids)
178
178
  klass, foreign_key = metadata.klass, metadata.foreign_key
179
179
  eager_loaded = klass.any_in(foreign_key => ids).entries
180
- unless eager_loaded.empty?
181
- eager_loaded.each do |doc|
182
- base_id = doc.__send__(foreign_key)
183
- yield(doc, { foreign_key => base_id })
184
- end
185
- else
186
- ids.each do |id|
187
- IdentityMap.clear_many(klass, { foreign_key => id })
188
- end
180
+ ids.each do |id|
181
+ IdentityMap.clear_many(klass, { foreign_key => id })
182
+ end
183
+ eager_loaded.each do |doc|
184
+ base_id = doc.__send__(foreign_key)
185
+ yield(doc, { foreign_key => base_id })
189
186
  end
190
187
  end
191
188
  end
@@ -232,6 +232,7 @@ module Mongoid
232
232
  criteria.update_all(foreign_key => nil)
233
233
  target.clear do |doc|
234
234
  unbind_one(doc)
235
+ doc.changed_attributes.delete(foreign_key)
235
236
  end
236
237
  end
237
238
  alias :nullify_all :nullify
@@ -309,7 +309,7 @@ module Mongoid
309
309
  !!@executed
310
310
  end
311
311
 
312
- # Reset the enumerable back to it's persisted state.
312
+ # Reset the enumerable back to its persisted state.
313
313
  #
314
314
  # @example Reset the enumerable.
315
315
  # enumerable.reset
@@ -42,6 +42,7 @@ module Mongoid
42
42
  def flagged_for_destroy?
43
43
  @flagged_for_destroy ||= false
44
44
  end
45
+ alias :marked_for_destruction? :flagged_for_destroy?
45
46
 
46
47
  # Returns true if the +Document+ has been succesfully destroyed, and false
47
48
  # if it hasn't. This is determined by the variable @destroyed and NOT
@@ -4,7 +4,7 @@ module Mongoid
4
4
  module Queryable
5
5
 
6
6
  # Wrap the validation inside the an execution block that alert's the
7
- # session not to clear it's persistence options.
7
+ # session not to clear its persistence options.
8
8
  #
9
9
  # @example Execute the validation with a query.
10
10
  # with_query(document) do
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid
3
- VERSION = "3.0.9"
3
+ VERSION = "3.0.10"
4
4
  end
@@ -173,12 +173,32 @@ module Mongoid
173
173
  def only_versioned_attributes(hash)
174
174
  versioned = {}
175
175
  hash.except("versions").each_pair do |name, value|
176
- field = fields[name]
177
- versioned[name] = value if !field || field.versioned?
176
+ add_versioned_attribute(versioned, name, value)
178
177
  end
179
178
  versioned
180
179
  end
181
180
 
181
+ # Add the versioned attribute. Will work now for localized fields.
182
+ #
183
+ # @api private
184
+ #
185
+ # @example Add the versioned attribute.
186
+ # model.add_versioned_attribute({}, "name", "test")
187
+ #
188
+ # @param [ Hash ] versioned The versioned attributes.
189
+ # @param [ String ] name The name of the field.
190
+ # @param [ Object ] value The value for the field.
191
+ #
192
+ # @since 3.0.10
193
+ def add_versioned_attribute(versioned, name, value)
194
+ field = fields[name]
195
+ if field && field.localized?
196
+ versioned["#{name}_translations"] = value
197
+ else
198
+ versioned[name] = value if !field || field.versioned?
199
+ end
200
+ end
201
+
182
202
  module ClassMethods
183
203
 
184
204
  # Sets the maximum number of versions to store.
@@ -4,13 +4,14 @@ module Rack
4
4
  module Middleware
5
5
 
6
6
  # This middleware contains the behaviour needed to properly use the
7
- # identity map in Rack based applications.
7
+ # identity map in Rack based applications. This middleware will properly
8
+ # handle Rails or Rack streaming responses.
8
9
  class IdentityMap
9
10
 
10
11
  # Initialize the new middleware.
11
12
  #
12
13
  # @example Init the middleware.
13
- # IdentityMap.new(app)
14
+ # IdentityMap.new(app)
14
15
  #
15
16
  # @param [ Object ] app The application.
16
17
  #
@@ -22,7 +23,7 @@ module Rack
22
23
  # Make the request with the provided environment.
23
24
  #
24
25
  # @example Make the request.
25
- # identity_map.call(env)
26
+ # identity_map.call(env)
26
27
  #
27
28
  # @param [ Object ] env The environment.
28
29
  #
@@ -30,7 +31,11 @@ module Rack
30
31
  #
31
32
  # @since 2.1.0
32
33
  def call(env)
33
- ::Mongoid.unit_of_work { @app.call(env) }
34
+ response = @app.call(env)
35
+ response[2] = ::Rack::BodyProxy.new(response[2]) do
36
+ ::Mongoid::IdentityMap.clear
37
+ end
38
+ response
34
39
  end
35
40
  end
36
41
  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: 3.0.9
4
+ version: 3.0.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-11 00:00:00.000000000 Z
12
+ date: 2012-10-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -352,7 +352,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
352
352
  version: '0'
353
353
  segments:
354
354
  - 0
355
- hash: 3436548235215749672
355
+ hash: 1575250359418632703
356
356
  required_rubygems_version: !ruby/object:Gem::Requirement
357
357
  none: false
358
358
  requirements: