Skip to content

Commit 998f4d5

Browse files
authored
MONGOID-5034 When excluded from query, embeds many relations are returned as empty array instead of raising MissingAttributeError (#5196)
* MONGOID-5034 add test and potential implementation * MONGOID-5034 add embedded condition with comment * MONGOID-5034 only raise when not binding * MONGOID-5034 update comments * MONGOID-5034 dont raise during without_autobuild * MONGOID-5034 update comments
1 parent b23e999 commit 998f4d5

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

lib/mongoid/association/accessors.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,19 @@ def set_relation(name, relation)
105105
#
106106
# @return [ Proxy ] The association.
107107
def get_relation(name, association, object, reload = false)
108+
field_name = database_field_name(name)
109+
110+
# As per the comments under MONGOID-5034, I've decided to only raise on
111+
# embedded associations for a missing attribute. Rails does not raise
112+
# for a missing attribute on referenced associations.
113+
# We also don't want to raise if we're retrieving an association within
114+
# the codebase. This is often done when retrieving the inverse association
115+
# during binding or when cascading callbacks. Whenever we retrieve
116+
# associations within the codebase, we use without_autobuild.
117+
if !without_autobuild? && association.embedded? && attribute_missing?(field_name)
118+
raise ActiveModel::MissingAttributeError, "Missing attribute: '#{field_name}'"
119+
end
120+
108121
if !reload && (value = ivar(name)) != false
109122
value
110123
else

spec/mongoid/association/embedded/embeds_many_query_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,17 @@
4747
expect(patient.addresses.first.number).to eq(123)
4848
end
4949
end
50+
51+
context "when excluding the relation" do
52+
let(:congress) do
53+
EmmCongress.where(name: 'foo').only(:_id).first
54+
end
55+
56+
it 'raises a MissingAttributeError' do
57+
expect do
58+
congress.legislators
59+
end.to raise_error(ActiveModel::MissingAttributeError)
60+
end
61+
end
5062
end
5163
end

0 commit comments

Comments
 (0)