Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-5537

Cascade callbacks on embedded documents incorrectly set timestamps

    • Type: Icon: Bug Bug
    • Resolution: Won't Fix
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: 7.0.13, 8.0.3
    • Component/s: Callbacks
    • None

      Cascaded callbacks don't appear to set the updated_at time correctly when using Mongoid::Timestamp. This can be seen in this minimal working example:

      class Parent
        include Mongoid::Document
        include Mongoid::Timestamps
      
        embeds_one :child, cascade_callbacks: true
      end
      
      class Child
        include Mongoid::Document
        include Mongoid::Timestamps
      
        after_save :run_callback
      
        field :updateable_field
      
        embedded_in :parent
      
        def run_callback
          puts("after save my updated_at time is #{updated_at}")
        end
      end
      
      puts("Create the starting conditions")
      parent = Parent.new
      parent.child = Child.new
      
      puts("Save the parent, which will output a string where {{updated_at}} is nil in the after_save run_callback on Child")
      parent.save!
      
      puts("Show the updated_at values _are_ set correctly afterwards")
      puts("Parent updated at #{parent.updated_at}, Child updated at #{parent.child.updated_at}")
      
      puts("Update the Child and save it directly - {{updated_at}} in callback is correct")
      parent.child.updateable_field = 'new_value'
      parent.child.save!
      
      puts("Update the Child and save the Parent - {{updated_at}} in callback is incorrect")
      parent.child.updateable_field = 'newer_value'
      parent.save!
      
      puts("But again, afterwards, it _is_ correct")
      puts("Parent updated at #{parent.updated_at}, Child updated at #{parent.child.updated_at}")
      

      which will output something like the following:

      Create the starting conditions
      
      Save the parent, which will output a string where {{updated_at}} is nil in the after_save run_callback on Child            
      after save my updated_at time is
      
      Show the updated_at values _are_ set correctly afterwards
      Parent updated at 2022-12-16 10:47:48 UTC, Child updated at 2022-12-16 10:47:48 UTC
      
      Update the Child and save it directly - {{updated_at}} in callback is correct
      after save my updated_at time is 2022-12-16 10:59:28 UTC
      
      Update the Child and save the Parent - {{updated_at}} in callback is incorrect
      after save my updated_at time is 2022-12-16 10:59:28 UTC 
      
      But again, afterwards, it _is_ correct
      Parent updated at 2022-12-16 11:00:00 UTC, Child updated at 2022-12-16 11:00:00 UTC
      

      This causes the updated_at value seen within a callback on the Child object to be the previous time the object was updated, if save is called on its Parent and cascade_callbacks is true.

      I tested this in Mongoid 7.0.13 and confirmed it's still the case in 8.0.3.

            Assignee:
            jamis.buck@mongodb.com Jamis Buck
            Reporter:
            rob@robheath.me.uk Rob Heath
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: