-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: 9.0.0, 8.1.5, 8.0.8
-
Component/s: Persistence, Validations
-
None
This report comes from GitHub (https://github.com/mongodb/mongoid/discussions/5805):
Hello! We've just upgraded from v8.1.4 to v8.1.5 and our tests are failing, which alerted us to the following behaviour change.
We have a parent model with embedded list of child documents like so :
class Whole include Mongoid::Document embeds_many :parts accepts_nested_attributes_for :parts def errors parts.map do |part| part.errors.full_messages if part.errors.present? end end end class Part include Mongoid::Document embedded_in :whole field :title, type: String validates :title, presence: true end
Before the update, if I had a Whole with multiple failing invalid Parts, it would return all validation messages of all parts. Seems like previously .valid? was triggered on all children when .valid? was called on the parent (objects were created with nested attributes.
whole = Whole.new(parts: [{title: "1"}, {title: ""}, {title: ""}] whole.valid? => false whole.errors => ["Title can't be blank", "Title can't be blank"]
However AFTER the new update, we are no longer getting any validation error messages past the first one - unless the child part .valid? is explicitly called.
whole = Whole.new(parts: [{title: "1"}, {title: ""}, {title: ""}] whole.valid? => false whole.errors => ["Title can't be blank"] whole.parts[1].errors => ["Title can't be blank"] whole.parts[2].errors => [] whole.parts[2].valid? => false whole.parts[2].errors => ["Title can't be blank"] whole.errors => ["Title can't be blank"] whole.valid? => false whole.errors => ["Title can't be blank", "Title can't be blank"]
Additionally after some more debugging on the new version we found that the validations for multiple embedded association was NOT triggered when parts were created these ways:
- whole.parts.build(....)
- Nested attributes Whole.new(..., parts: [...])
But however DOES get triggered if you do
- whole.parts << Part.new(...) or
- whole.parts = [Part.new(...), ...]
Any light shed on this would be greatly appreciated. Thank you!