Skip to content
22 changes: 21 additions & 1 deletion lib/mongoid/association/embedded/embeds_many/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -601,11 +601,31 @@ def as_attributes
# @api private
def update_attributes_hash
if _target.empty?
_base.attributes.delete(_association.store_as)
handle_empty_target
else
_base.attributes.merge!(_association.store_as => _target.map(&:attributes))
end
end

# Handle the case when the target is empty.
#
# @api private
def handle_empty_target
# Only persist empty array if:
# 1. We're explicitly assigning (setter was called), OR
# 2. The attribute key already exists (replacing existing data with empty)
if _assigning? || _base.attributes.key?(_association.store_as)
# Only mark as changed if the attribute is not already an empty array
unless _base.attributes[_association.store_as] == []
_base.send(:attribute_will_change!, _association.store_as)
end
_base.attributes[_association.store_as] = []
else
# During initialization with no prior data, delete the key to maintain
# the original behavior of not persisting unassigned empty associations
_base.attributes.delete(_association.store_as)
end
end
end
end
end
Expand Down
19 changes: 19 additions & 0 deletions spec/mongoid/association/embedded/embeds_many/proxy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4271,6 +4271,25 @@ class TrackingIdValidationHistory
end
end

context "when setting an embedded relation to an empty array" do
let(:document) do
Person.create!
end

let(:person) do
Person.find(document.id)
end

before do
person.update_attributes!(addresses: [])
end

it "sets the embedded relation to an empty array" do
expect(person.addresses).to be_empty
expect(person.attributes.keys).to include("addresses")
end
end

context "when pushing with a before_add callback" do

let(:artist) do
Expand Down
Loading