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

Autosave does not cascade unless all items are "dirty"

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Minor - P4 Minor - P4
    • 7.0.0
    • Affects Version/s: 5.0.0
    • Component/s: None
    • None
    • Environment:
      {OS: "OS X 10.10.5", Rails: 4.1.7, Mongoid: 5.0.0}

      Setup

      Consider the three-level has_one/belongs_to relationship, (where X <-- Y means Y belongs_to X):

          Grandparent     <--     Parent     <--     Child
      

      (Class files at the bottom of this description)

      Note that for each has_one/belongs_to relationship, the :autosave option is set to true.

      Repro Steps

      1. Create the instances, g, p and c
      2. Change a field on c
      3. Call g.save
      4. Notice that c does not save
      5. Change a field on p
      6. Call g.save again
      7. Notice that both c and p have saved

      Here is an example from the Rails console:

      2.2.2 :001 > g = Grandparent.create!(:name => 'Gertrude')
       => #<Grandparent _id: 56f3228a211d70035c000000, name: "Gertrude">
      2.2.2 :002 > p = Parent.create!(:name => 'Penny', :grandparent => g)
       => #<Parent _id: 56f322ad211d70035c000002, grandparent_id: BSON::ObjectId('56f3228a211d70035c000000'), name: "Penny">
      2.2.2 :004 > c = Child.create!(:name => 'Celine', :parent => p)
       => #<Child _id: 56f322c9211d70035c000003, parent_id: BSON::ObjectId('56f322ad211d70035c000002'), name: "Celine">
      2.2.2 :003 > c.changed?
       => false
      2.2.2 :004 > c.name = 'Cherise'
       => "Cherise"
      2.2.2 :005 > g.save!
       => true
      2.2.2 :006 > c.changed?
       => true
      2.2.2 :007 > c.reload
       => #<Child _id: 56f322c9211d70035c000003, parent_id: BSON::ObjectId('56f322ad211d70035c000002'), name: "Celine">
      2.2.2 :008 > c.name
       => "Celine"
      2.2.2 :009 > c.name = 'Cherise'
       => "Cherise"
      2.2.2 :010 > p.name = 'Penelope'
       => "Penelope"
      2.2.2 :011 > g.save!
       => true
      2.2.2 :012 > c.reload
       => #<Child _id: 56f322c9211d70035c000003, parent_id: BSON::ObjectId('56f322ad211d70035c000002'), name: "Cherise">
      2.2.2 :013 > c.name
       => "Cherise"
      

      Justification for Calling this a Bug

      It's clear that calling g.save is intended to cascade to c, since if we change p, the cascade is successful. I can think of no use case where we'd want to interrupt the autosaves only in the event that one item in the chain has not been changed.



      Example Class Files:

      grandparent.rb
      class Grandparent
        include Mongoid::Document
        has_one :parent, :autosave => true
        field :name, :type => String
      end
      
      parent.rb
      class Parent
        include Mongoid::Document
        belongs_to :grandparent
        has_one :child, :autosave => true
        field :name, :type => String
      end
      
      child.rb
      class Child
        include Mongoid::Document
        belongs_to :parent
        field :name, :type => String
      end
      

            Assignee:
            emily.stolfo Emily Stolfo
            Reporter:
            shealen.clare@gmail.com Shealen Clare
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: