3 votes

Laravel Eager Load Relations polymorphes multiples - certaines suppressions douces, d'autres non

J'ai plusieurs modèles qui contiennent un champ polymorphe. Ces champs polymorphes contiennent chacun quatre ou cinq relations, certaines sont supprimables, d'autres non. Je suis confronté à un problème de type "damné si vous le faites, damné si vous ne le faites pas" et je ne sais pas comment le résoudre.

Si je charge avec un appel au chargement empressé sans inclure les trashed sur les modèles qui ont des softdeletes :

$deptRisks = \App\DeptRisk::with(['owner', 'riskable']);

J'obtiendrai l'erreur suivante sur les modèles qui ont été supprimés :

Essayer d'obtenir la propriété d'un non-objet

Si je charge AVEC le withTrashed pour les softdeletes :

$deptRisks = \App\DeptRisk::with(['owner', 'riskable' => function ($query) {
        $query->withTrashed();
}]);

J'obtiendrai l'erreur suivante sur les modèles qui n'ont PAS été configurés en tant que soft-deletes :

Appel à une méthode non définie Illuminez \Database\Query\Builder ::withTrashed()

Je suis sûr que je rate quelque chose d'évident, mais je tourne en rond. Aidez-moi, s'il vous plaît.

0voto

Watercayman Points 708

J'ai une réponse, mais pas une solution. Je ne pense pas que cela soit possible avec Laravel actuellement, ce qui est regrettable.

Une solution de contournement serait d'appliquer cette règle au niveau de la relation. Par exemple, créer deux relations distinctes, riskable et riskableWithTrashed. Vous pourriez ensuite les appeler toutes les deux au cours du processus de chargement, l'une sans la fermeture, l'autre avec. Cette méthode permettrait de charger tous les modèles avec succès, mais elle présente plusieurs inconvénients, le pire étant de devoir toujours créer une logique de vérification de l'utilisation de la collection (un champ devient essentiellement deux).

J'ai choisi de ne pas l'utiliser, mais plutôt de revenir en arrière et de transformer les relations polymorphes non soft-delete en soft deletions. Ce n'est pas une solution efficace, mais après deux jours d'échec de la combinaison, j'ai réussi.

0voto

Bonjour, vous pouvez essayer quelque chose comme ceci lorsque vous définissez la relation :

public function riskable() {
    $builder = $this->morphTo();

    if (method_exists($builder, 'withTrashed')) {
        $builder->withTrashed();
    }

    return $builder;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X