Skip to content

Commit 3d3abdc

Browse files
MONGOID 5800 When initializing an embedded association with an invalid hash, got undefined method `with_indifferent_access' error (#6075)
* Adds support for single hash input in nested attributes for has_many associations. * Adding a check to initialize() * add with_indifferent_access to array * fixing how we handle arrays * empty commit * adding more guards in build() * Adding handling for if the array has uneven number of elements
1 parent 17d8df3 commit 3d3abdc

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

lib/mongoid/association/nested/many.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ class Many
1616
# This attempts to perform 3 operations, either one of an update of
1717
# the existing association, a replacement of the association with a new
1818
# document, or a removal of the association.
19+
#
20+
# It raises an argument error if the attributes are not a Hash or an
21+
# Array of key/value pairs.
1922
#
2023
# @example Build the nested attrs.
2124
# many.build(person)
@@ -32,8 +35,12 @@ def build(parent, options = {})
3235
attributes.each do |attrs|
3336
if attrs.is_a?(::Hash)
3437
process_attributes(parent, attrs.with_indifferent_access)
35-
else
38+
elsif attrs.is_a?(Array) && attrs.length > 1 && attrs[1].respond_to?(:with_indifferent_access)
3639
process_attributes(parent, attrs[1].with_indifferent_access)
40+
elsif attrs.is_a?(Array) && attrs.length.even?
41+
process_attributes(parent, Hash[*attrs].with_indifferent_access)
42+
else
43+
raise ArgumentError, "Attributes for nested association '#{association.name}' must be a Hash or an Array of key/value pairs."
3744
end
3845
end
3946
end

spec/integration/associations/embeds_many_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,4 +327,20 @@ class Comment
327327
end
328328
end
329329
end
330+
331+
context "when a hash is provided instead of an array for an embeds_many association" do
332+
let(:post) { EmbedsManySpec::Post.new(title: 'Broken post', comments: { content: 'Comment' }) }
333+
334+
it "does not raise an error on initialization" do
335+
expect { post }.to_not raise_error
336+
end
337+
338+
it "does not raise an error when accessing the association" do
339+
expect { post.comments }.to_not raise_error
340+
end
341+
342+
it "allows building new documents on the association" do
343+
expect(post.comments.build).to be_a EmbedsManySpec::Comment
344+
end
345+
end
330346
end

0 commit comments

Comments
 (0)