Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-5757

Parent validation does not trigger all of embedded documents validation

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 9.0.0, 8.1.5
    • Component/s: Persistence, Validations
    • Labels:
      None
    • Ruby Drivers

      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!

            Assignee:
            Unassigned Unassigned
            Reporter:
            jamis.buck@mongodb.com Jamis Buck
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: