Skip to content

Commit 7fb592c

Browse files
committed
Add validation to ensure child can't be linked to multiple parents
Resolves https://github.com/alphagov/whitehall/pull/11431/changes#r3258493572
1 parent 3c0a9d8 commit 7fb592c

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

app/models/parent_child_relationship.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class ParentChildRelationship < ApplicationRecord
1212
uniqueness: { scope: :parent_edition_id }
1313

1414
validate :parent_must_be_prepublication, on: :create
15+
validate :child_document_must_have_no_other_parent, on: :create
1516

1617
private
1718

@@ -24,4 +25,16 @@ def parent_must_be_prepublication
2425
errors.add(:parent_edition, "does not support child documents")
2526
end
2627
end
28+
29+
def child_document_must_have_no_other_parent
30+
return if parent_edition.blank? || child_document.blank? # These are already covered by presence validation
31+
32+
existing_relationships = ParentChildRelationship.where(child_document_id: child_document_id)
33+
if existing_relationships.count.positive?
34+
document_ids = existing_relationships.map { |r| r.parent_edition.document.id }.uniq
35+
unless parent_edition.document.id.in?(document_ids)
36+
errors.add(:child_document, "is already linked to a different parent document")
37+
end
38+
end
39+
end
2740
end

test/unit/app/models/parent_child_relationship_test.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,31 @@ class ParentChildRelationshipTest < ActiveSupport::TestCase
4040
assert_not relationship.valid?
4141
end
4242

43+
test "should be invalid if child has existing relationship with another parent" do
44+
parent_document_one = create(:document)
45+
parent_document_two = create(:document)
46+
parent_edition_one = create(:draft_standard_edition, document: parent_document_one, configurable_document_type: "parent_type")
47+
parent_edition_two = create(:draft_standard_edition, document: parent_document_two, configurable_document_type: "parent_type")
48+
child_document = create(:document)
49+
50+
existing_relationship = create(
51+
:parent_child_relationship,
52+
parent_edition: parent_edition_one,
53+
child_document:,
54+
)
55+
additional_relationship = build(
56+
:parent_child_relationship,
57+
parent_edition: parent_edition_two,
58+
child_document:,
59+
)
60+
assert existing_relationship.valid?
61+
assert_not additional_relationship.valid?
62+
assert_includes(
63+
additional_relationship.errors[:child_document],
64+
"is already linked to a different parent document",
65+
)
66+
end
67+
4368
test "should be valid if one parent edition has two separate child documents" do
4469
parent_edition = @valid_parent_edition
4570

0 commit comments

Comments
 (0)