fix: cascade delete attribute values when attribute definition is removed

FK on attribute_values.attribute_definition_id now uses ON DELETE CASCADE
so deleting an AttributeDefinition also clears its values from all
articles. Admin delete action shows a confirmation warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Simon Kuehn 2026-05-18 11:02:46 +00:00
parent 5b2a200fc2
commit b908e44a6e
5 changed files with 41 additions and 1 deletions

View file

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20260520060000 extends AbstractMigration
{
public function getDescription(): string
{
return 'Cascade delete attribute_values when attribute_definition is deleted';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE app.attribute_values DROP CONSTRAINT fk_6f6a862d7492f274');
$this->addSql('ALTER TABLE app.attribute_values ADD CONSTRAINT fk_6f6a862d7492f274 FOREIGN KEY (attribute_definition_id) REFERENCES app.attribute_definitions (id) ON DELETE CASCADE');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE app.attribute_values DROP CONSTRAINT fk_6f6a862d7492f274');
$this->addSql('ALTER TABLE app.attribute_values ADD CONSTRAINT fk_6f6a862d7492f274 FOREIGN KEY (attribute_definition_id) REFERENCES app.attribute_definitions (id)');
}
}

View file

@ -21,7 +21,7 @@ class AttributeValue
private Article $article;
#[ORM\ManyToOne(targetEntity: AttributeDefinition::class)]
#[ORM\JoinColumn(nullable: false)]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private AttributeDefinition $attributeDefinition;
#[ORM\Column(type: 'text')]

View file

@ -7,6 +7,8 @@ namespace App\Infrastructure\Http\Controller\Admin;
use App\Domain\Article\AttributeDefinition;
use App\Domain\Article\AttributeType;
use App\Infrastructure\Http\Form\StringArrayType;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
@ -24,6 +26,14 @@ final class AttributeDefinitionCrudController extends AbstractCrudController
return AttributeDefinition::class;
}
public function configureActions(Actions $actions): Actions
{
return $actions
->update(Crud::PAGE_INDEX, Action::DELETE, static fn (Action $a) => $a
->askConfirmation(new TranslatableMessage('action.delete_attribute_confirm', [], 'admin'))
);
}
public function configureCrud(Crud $crud): Crud
{
return $crud

View file

@ -77,6 +77,7 @@ field.locale: Sprache
field.domain: Bereich
field.translation_key: Schlüssel
field.translation_value: Übersetzung
action.delete_attribute_confirm: 'Attribut löschen? Alle gespeicherten Werte in bestehenden Artikeln werden ebenfalls gelöscht.'
action.retry: Wiederholen
action.retry_confirm: 'Diesen Pipeline-Job ab dem aktuellen Schritt neu einreihen?'
action.rerun_ai: 'KI neu starten'

View file

@ -77,6 +77,7 @@ field.locale: Locale
field.domain: Domain
field.translation_key: Key
field.translation_value: Value
action.delete_attribute_confirm: 'Delete this attribute? All values stored on existing articles will also be deleted.'
action.retry: Retry
action.retry_confirm: 'Re-queue this pipeline job from the current step?'
action.rerun_ai: 'Re-run AI'