Skip to content

Commit 5c1c60f

Browse files
authored
MONGOID-5352 assign_attributes is working incorrectly since 7.3.4 (#5274)
* MONGOID-5352 add fix for this issue, other tests failing * MONGOID-5352 fix two tests, two to go * MONGOID-5352 fix all tests * MONGOID-5352 fix some tests * MONGOID-5352 don't set caches before setting association * MONGOID-5352 rework solution * Update lib/mongoid/association/embedded/batchable.rb * MONGOID-5352 answer comments * MONGOID-5352 update comment
1 parent cef142b commit 5c1c60f

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

lib/mongoid/association/embedded/batchable.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ def batch_remove(docs, method = :delete)
8585
def batch_replace(docs)
8686
if docs.blank?
8787
if _assigning? && !empty?
88-
_base.delayed_atomic_sets.clear
88+
_base.delayed_atomic_sets.delete(path)
89+
clear_atomic_path_cache
8990
_base.add_atomic_unset(first)
9091
target_duplicate = _target.dup
9192
pre_process_batch_remove(target_duplicate, :delete)
@@ -97,7 +98,8 @@ def batch_replace(docs)
9798
_base.delayed_atomic_sets.clear unless _assigning?
9899
docs = normalize_docs(docs).compact
99100
_target.clear and _unscoped.clear
100-
_base.delayed_atomic_unsets.clear
101+
_base.delayed_atomic_unsets.delete(path)
102+
clear_atomic_path_cache
101103
inserts = execute_batch_set(docs)
102104
add_atomic_sets(inserts)
103105
end
@@ -246,6 +248,17 @@ def path
246248
end
247249
end
248250

251+
# Clear the cache for path and atomic_paths. This method is used when
252+
# the path method is used, and the association has not been set on the
253+
# document yet, which can cause path and atomic_paths to be calculated
254+
# incorrectly later.
255+
#
256+
# @api private
257+
def clear_atomic_path_cache
258+
self.path = nil
259+
_base.instance_variable_set("@atomic_paths", nil)
260+
end
261+
249262
# Set the atomic path.
250263
#
251264
# @api private

spec/mongoid/association/embedded/embeds_many/proxy_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4699,4 +4699,24 @@ class DNS::Record
46994699
end
47004700
end
47014701
end
4702+
4703+
context "when using assign_attributes with an already populated array" do
4704+
let(:post) { EmmPost.create! }
4705+
4706+
before do
4707+
post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'a'}],
4708+
user_tags: [{id: BSON::ObjectId.new, title: 'b'}])
4709+
post.save!
4710+
post.reload
4711+
post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'c'}],
4712+
user_tags: [])
4713+
post.save!
4714+
post.reload
4715+
end
4716+
4717+
it "has the correct embedded documents" do
4718+
expect(post.company_tags.length).to eq(1)
4719+
expect(post.company_tags.first.title).to eq("c")
4720+
end
4721+
end
47024722
end

spec/mongoid/association/embedded/embeds_many_models.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,29 @@ class EmmHatch
162162
# No :class_name option on this association intentionally.
163163
embedded_in :tank
164164
end
165+
166+
class EmmPost
167+
include Mongoid::Document
168+
169+
embeds_many :company_tags, class_name: "EmmCompanyTag"
170+
embeds_many :user_tags, class_name: "EmmUserTag"
171+
end
172+
173+
174+
class EmmCompanyTag
175+
include Mongoid::Document
176+
177+
field :title, type: String
178+
179+
embedded_in :post, class_name: "EmmPost"
180+
end
181+
182+
183+
class EmmUserTag
184+
include Mongoid::Document
185+
186+
field :title, type: String
187+
188+
embedded_in :post, class_name: "EmmPost"
189+
end
190+

0 commit comments

Comments
 (0)