diff options
Diffstat (limited to 'app/models/concerns/linkable_item.rb')
-rw-r--r-- | app/models/concerns/linkable_item.rb | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/app/models/concerns/linkable_item.rb b/app/models/concerns/linkable_item.rb new file mode 100644 index 00000000000..135252727ab --- /dev/null +++ b/app/models/concerns/linkable_item.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# == LinkableItem concern +# +# Contains common functionality shared between related issue links and related work item links +# +# Used by IssueLink, WorkItems::RelatedWorkItemLink +# +module LinkableItem + extend ActiveSupport::Concern + include FromUnion + include IssuableLink + + included do + validate :check_existing_parent_link + + scope :for_source, ->(item) { where(source_id: item.id) } + scope :for_target, ->(item) { where(target_id: item.id) } + scope :for_items, ->(source, target) do + where(source: source, target: target).or(where(source: target, target: source)) + end + + private + + def check_existing_parent_link + return unless source && target + + existing_relation = WorkItems::ParentLink.for_parents([source, target]).for_children([source, target]) + return if existing_relation.none? + + errors.add(:source, format(_('is a parent or child of this %{item}'), item: self.class.issuable_name)) + end + end +end + +LinkableItem.include_mod_with('LinkableItem::Callbacks') +LinkableItem.prepend_mod_with('LinkableItem') |