@@ -67,12 +67,13 @@ def validate_association(document, attribute)
6767 valid = document . validating do
6868 # Now, treating the target as an array, look at each element
6969 # and see if it is valid, but only if it has already been
70- # persisted, or changed, and hasn't been flagged for destroy.
70+ # persisted, or changed, and hasn't been flagged for destroy
71+ # or already destroyed.
7172 #
7273 # use map.all? instead of just all?, because all? will do short-circuit
7374 # evaluation and terminate on the first failed validation.
7475 list . map do |value |
75- if value && ! value . flagged_for_destroy? && ( ! value . persisted? || value . changed? )
76+ if needs_validation? ( value )
7677 value . validated? || value . valid?
7778 else
7879 true
@@ -120,6 +121,21 @@ def get_target_documents_for_has_many(target)
120121 def get_target_documents_for_other ( target )
121122 Array . wrap ( target )
122123 end
124+
125+ # Returns true if the given value should be validated as part of
126+ # an associated validation. Destroyed and flagged-for-destroy
127+ # documents are skipped, as are persisted documents that haven't
128+ # changed.
129+ #
130+ # @param [ Mongoid::Document | nil ] value The value to check.
131+ #
132+ # @return [ true | false ] Whether the value needs validation.
133+ def needs_validation? ( value )
134+ value &&
135+ !value . flagged_for_destroy? &&
136+ !value . destroyed? &&
137+ ( !value . persisted? || value . changed? )
138+ end
123139 end
124140 end
125141end
0 commit comments