diff options
Diffstat (limited to 'lib/gitlab/import/errors.rb')
-rw-r--r-- | lib/gitlab/import/errors.rb | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/gitlab/import/errors.rb b/lib/gitlab/import/errors.rb new file mode 100644 index 00000000000..b9e8c9135fd --- /dev/null +++ b/lib/gitlab/import/errors.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Gitlab + module Import + module Errors + # Merges all nested subrelation errors into base errors object. + # + # @example + # issue = Project.last.issues.new( + # title: 'test', + # author: User.first, + # notes: [Note.new( + # award_emoji: [AwardEmoji.new(name: 'test')] + # )]) + # + # issue.validate + # issue.errors.full_messages + # => ["Notes is invalid"] + # + # Gitlab::Import::Errors.merge_nested_errors(issue) + # issue.errors.full_messages + # => ["Notes is invalid", + # "Award emoji is invalid", + # "Awardable can't be blank", + # "Name is not a valid emoji name", + # ... + # ] + def self.merge_nested_errors(object) + object.errors.each do |error| + association = object.class.reflect_on_association(error.attribute) + + next unless association&.collection? + + records = object.public_send(error.attribute).select(&:invalid?) # rubocop: disable GitlabSecurity/PublicSend + + records.each do |record| + merge_nested_errors(record) + + object.errors.merge!(record.errors) + end + end + end + end + end +end |