-
Type: Bug
-
Resolution: Done
-
Priority: Minor - P4
-
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:
class Grandparent include Mongoid::Document has_one :parent, :autosave => true field :name, :type => String end
class Parent include Mongoid::Document belongs_to :grandparent has_one :child, :autosave => true field :name, :type => String end
class Child include Mongoid::Document belongs_to :parent field :name, :type => String end
- is related to
-
MONGOID-3072 Callbacks not called on embedded document when not dirty (even with cascaded callbacks enabled)
- Closed