9.0.7 revert of child validations causes grandchild records not to validated/persisted

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • None
    • Ruby Drivers
    • None
    • None
    • None
    • None
    • None
    • None

      The revert in 9.0.7 has caused breakages for our application.

      Before, when saving a parent object, it would validate all children, and children of those children, etc. I understand why this was reverted for performance reasons, but doing so has left a use case no longer working.

      When you has three levels, Parent, Child, Grandchild, and using accepts_nested_attributes_for you update only the grandchild from the parent record, 9.0.7 will no longer validate the grandchild record, because the child record is unchanged.

      This following reproduced the issue. Under 9.0.6, we get a validation issue as expected:

      message:
        Validation of Post failed.
      summary:
        The following errors were found: Comments is invalid
      

      But under 9.0.7, the script completes, and the nested comment validation no longer runs. If you uncomment the title setters, then validation returns.

      So the issue only affects when updating records deeper than th first two levels (i.e. grandchild, great grandchild, etc).

      require 'bundler/inline'
      
      gemfile do
        source 'https://rubygems.org'
        gem 'mongoid', '9.0.7'
      end
      
      Mongoid.configure do |config|
        config.clients.default = {
          hosts: ['localhost:27017'],
          database: 'mongoid_test',
        }
      end
      
      class Post
        include Mongoid::Document
      
        has_many :comments, inverse_of: :post
      
        accepts_nested_attributes_for :comments, allow_destroy: true
      
        field :title, type: String
      end
      
      class Comment
        include Mongoid::Document
      
        belongs_to :post, inverse_of: :comments
      
        belongs_to :parent, class_name: 'Comment', inverse_of: :comments, optional: true
      
        has_many :comments, inverse_of: :parent
      
        accepts_nested_attributes_for :comments, allow_destroy: true
      
        validates :num, numericality: { greater_than_or_equal_to: 0 }
      
        field :title, type: String
        field :num, type: Integer, default: 0
      end
      
      post = Post.create(title: 'Post 1')
      comment1 = post.comments.create(title: 'Comment 1')
      comment2 = post.comments.create(parent: comment1, title: 'Comment 2')
      
      puts 'Before:'
      puts post.inspect
      puts comment1.inspect
      puts comment2.inspect
      
      post.update!(
        # title: 'Post 1 - Updated',
        comments_attributes: [
          {
            _id: comment1.id,
            # title: 'Comment 1 - Updated',
            comments_attributes: [
              {
                _id: comment2.id,
                title: 'Comment 2 - Updated',
                num: -1,
              }
            ]
          }
        ]
      )
      
      puts 'After:'
      puts post.reload.inspect
      puts comment1.reload.inspect
      puts comment2.reload.inspect
      

              Assignee:
              Jamis Buck
              Reporter:
              Kieran Pilkington
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated: