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

Embedded doc doesn't know if parent is being destroyed in before_destroy callback

    • Type: Icon: Task Task
    • Resolution: Done
    • 2.4.0
    • Affects Version/s: None
    • Component/s: None
    • None

      I need to use cascading callbacks for various reasons. In an embedded doc's before_destroy there is currently no way to determine if the parent is being destroyed. flagged_for_destroy isn't being set in that case. I need to know this because in the case of just deleting the child I need to do certain things that wouldn't be done if the parent is being deleted.

      This is the current behavior I'm seeing:

      class Parent
        include Mongoid::Document
      
        embeds_many :childs, :cascade_callbacks => true
      
        before_destroy  :before_callback
        after_destroy   :after_callback
      
        def before_callback
          puts
          puts 'Parent#before_callback'
          puts "  flagged_for_destroy? = #{flagged_for_destroy?}"
          puts "  destroyed? = #{destroyed?}"
        end
      
        def after_callback
          puts
          puts 'Parent#after_callback'
          puts "  flagged_for_destroy? = #{flagged_for_destroy?}"
          puts "  destroyed? = #{destroyed?}"
        end
      end
      
      class Child
        include Mongoid::Document
      
        embedded_in :parent
      
        before_destroy  :before_callback
        after_destroy   :after_callback
      
        def before_callback
          puts
          puts 'Child#before_callback'
          puts "  parent is a #{parent.class} = #{parent.inspect}"
          puts "  parent.flagged_for_destroy? = #{parent.flagged_for_destroy?}"
          puts "  parent.destroyed? = #{parent.destroyed?}"
        end
      
        def after_callback
          puts
          puts 'Child#after_callback'
          puts "  parent is a #{parent.class} = #{parent.inspect}"
          puts "  parent.flagged_for_destroy? = #{parent.flagged_for_destroy?}"
          puts "  parent.destroyed? = #{parent.destroyed?}"
        end
      end
      
      p = Parent.new
      p.childs.create
      p.save
      p.destroy
      

      produces this output:

      Child#before_callback
        parent is a Parent = #<Parent _id: 4ed2b0d98035442c11000001, _type: nil>
        parent.flagged_for_destroy? = false
        parent.destroyed? = false
      
      Parent#before_callback
        flagged_for_destroy? = false
        destroyed? = false
      
      Parent#after_callback
        flagged_for_destroy? = false
        destroyed? = true
      
      Child#after_callback
        parent is a Parent = #<Parent _id: 4ed2b0d98035442c11000001, _type: nil>
        parent.flagged_for_destroy? = false
        parent.destroyed? = true
      

      I'm pretty sure this isn't the right way to do it, but if I set the flagged_for_destroy bool in Persistance#destroy (https://github.com/iamnader/mongoid-2/commit/6645e1f1db4b3697fdf91b1526cac1fd5c3b7b47) than I get these results which seem to make a lot more sense to me:

      Child#before_callback
        parent is a Parent = #<Parent _id: 4ed30133803544342d000001, _type: nil>
        parent.flagged_for_destroy? = true
        parent.destroyed? = false
      
      Parent#before_callback
        flagged_for_destroy? = true
        destroyed? = false
      
      Parent#after_callback
        flagged_for_destroy? = true
        destroyed? = true
      
      Child#after_callback
        parent is a Parent = #<Parent _id: 4ed30133803544342d000001, _type: nil>
        parent.flagged_for_destroy? = true
        parent.destroyed? = true
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            nader Nader Akhnoukh
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: