lib/mongoid/touchable.rb in mongoid-7.2.6 vs lib/mongoid/touchable.rb in mongoid-7.3.0

- old
+ new

@@ -28,14 +28,33 @@ current = Time.now field = database_field_name(field) write_attribute(:updated_at, current) if respond_to?("updated_at=") write_attribute(field, current) if field - touches = touch_atomic_updates(field) - unless touches["$set"].blank? - selector = atomic_selector - _root.collection.find(selector).update_one(positionally(selector, touches), session: _session) + # If the document being touched is embedded, touch its parents + # all the way through the composition hierarchy to the root object, + # because when an embedded document is changed the write is actually + # performed by the composition root. See MONGOID-3468. + if _parent + # This will persist updated_at on this document as well as parents. + # TODO support passing the field name to the parent's touch method; + # I believe it should be read out of + # _association.inverse_association.options but inverse_association + # seems to not always/ever be set here. See MONGOID-5014. + _parent.touch + else + # If the current document is not embedded, it is composition root + # and we need to persist the write here. + touches = touch_atomic_updates(field) + unless touches["$set"].blank? + selector = atomic_selector + _root.collection.find(selector).update_one(positionally(selector, touches), session: _session) + end end + + # Callbacks are invoked on the composition root first and on the + # leaf-most embedded document last. + # TODO add tests, see MONGOID-5015. run_callbacks(:touch) true end end