Dieser Artikel stammt von https://medium.com/@hafiqiqmal93/laravel-softdelete-avoiding-the-unique-constraint-problem-45381d9745a0
Falls Sie Laravel schon länger verwenden, insbesondere wenn es bei Projekten um Datenintegrität geht, sind Sie höchstwahrscheinlich bereits auf die SoftDelete-Funktion gestoßen. Ziemlich nützlich, weil Sie Datensätze „löschen“ können, ohne sie wirklich aus der Datenbank zu entfernen. Was Laravel tut, ist einfach einen Zeitstempel „deleded_at“ hinzuzufügen, sodass es als gelöscht markiert wird, aber im System verbleibt. Das ist alles schön und gut, um historische Daten aufzubewahren, aber es bringt ein potenziell heikles Problem mit sich: Was passiert mit eindeutigen Einschränkungen, wenn Sie vorläufig gelöschte Datensätze wiederherstellen?
Dies wird zu einem Problem, wenn Sie einen Datensatz wiederherstellen möchten, der beispielsweise bereits eine eindeutige E-Mail-Adresse oder einen eindeutigen Benutzernamen in der Datenbank enthält. Laravel wird einfach einen Fehler auslösen und das Verfahren stoppen. Glücklicherweise gibt es eine einfache Möglichkeit, dieses Problem auf sehr saubere Weise zu vermeiden.
Lassen Sie uns eine Lösung mit einer Eigenschaft durchgehen, die Ihnen hilft, die einzigartigen Einschränkungen bei der Verwendung von SoftDelete in Laravel zu umgehen.
Nehmen wir ein einfaches Beispiel. Stellen Sie sich vor, Sie haben eine Benutzertabelle mit einem E-Mail-Feld, das eindeutig sein muss:
Schema::create('users', function (Blueprint $table) { $table->string('email')->unique(); $table->softDeletes(); });
Wenn Sie einen Benutzer mit der E-Mail-Adresse [email protected] vorläufig löschen und später einen neuen Benutzer mit derselben E-Mail-Adresse erstellen, beschwert sich Laravel über die Eindeutigkeitsbeschränkung im E-Mail-Feld und gibt einen Fehler aus. Wenn Sie in der gleichen Situation versuchen, den gelöschten Benutzer wiederherzustellen, beschwert sich Laravel auch über die Eindeutigkeitsbeschränkung für das E-Mail-Feld und gibt denselben Fehler aus.
Dies kann zu Kopfschmerzen führen, insbesondere wenn es sich um große Systeme handelt, bei denen die Wiederherstellung von Datensätzen eine häufige Aufgabe ist.
Um dies zu verhindern, können wir die Werte eindeutiger Felder vorübergehend ändern, wenn ein Datensatz vorläufig gelöscht wird, und die ursprünglichen Werte wiederherstellen, wenn der Datensatz wiederhergestellt wird. Auf diese Weise stolpert die Datenbank bei vorläufigen Löschungen oder Wiederherstellungen nicht über die Eindeutigkeitsbeschränkung.
Ein Laravel-Merkmal ist eine großartige Möglichkeit, diese Funktionalität zu kapseln. Hier ist eine Eigenschaft, mit der wir das Problem lösen können:
trashed()) { foreach ($model->getDuplicateAvoidColumns() as $column) { // handle for Spatie Translatable library if (method_exists($model, 'getTranslatableAttributes')) { $translates = $model->getTranslatableAttributes(); if (in_array($column, $translates)) { foreach ($translates as $translate) { if ($translate === $column) { $values = $model->getTranslations($column); foreach ($values as $translation => $value) { $values[$translation] = (explode('--', $value)[1] ?? $value); } $model->setTranslations($column, $values); break; } } continue; } } if ($value = (explode('--', $model->{$column})[1] ?? null)) { $model->{$column} = $value; } } } }); static::deleted(function ($model): void { foreach ($model->getDuplicateAvoidColumns() as $column) { // handle for Spatie Translatable library if (method_exists($model, 'getTranslatableAttributes')) { $translates = $model->getTranslatableAttributes(); if (in_array($column, $translates)) { foreach ($translates as $translate) { if ($translate === $column) { $values = $model->getTranslations($column); foreach ($values as $translation => $value) { $values[$translation] = time() . '--' . $value; } $model->setTranslations($column, $values); break; } } continue; } } $model->{$column} = time() . '--' . $model->{$column}; } $model->save(); }); } }
Diese Eigenschaft bewirkt mehrere Dinge:
So können Sie diese Eigenschaft in Ihrem Laravel-Modell anwenden:
class User extends Model { use SoftDeletes, AvoidDuplicateConstraintSoftDelete; // Specify which columns should avoid the unique constraint issue public function getDuplicateAvoidColumns(): array { return ['email', 'username']; } }
Indem Sie die Eigenschaft **AvoidDuplicateConstraintSoftDelete** zu Ihrem Modell hinzufügen und angeben, welche Spalten eindeutige Einschränkungskonflikte vermeiden müssen (wie E-Mail und Benutzername), können Sie diese Probleme leicht verhindern .
Das bedeutet, dass es im Falle eines vorläufigen Löschens eines Datensatzes aufgrund einiger eindeutiger Einschränkungen keinen Konflikt mit weiteren Vorgängen geben würde. Oder mit anderen Worten: Auf diese Weise können Sie durch Anhängen des Zeitstempels an eindeutige Felder den Datensatz für die Datenbank im Hinblick auf die Eindeutigkeit „versteckt“ machen, aber bei Bedarf dennoch wiederherstellbar sein.
Dies ist sehr nützlich, wenn Sie mit einer großen Datenbank arbeiten und die Wiederherstellung von Datensätzen häufig vorkommt. Sie müssen sich nicht jedes Mal mit dem Fehler „doppelter Eintrag“ herumschlagen, wenn Sie einen vorläufig gelöschten Benutzer oder ein anderes Modell mitbringen.
Das Nützlichste in Laravel ist SoftDelete, aber manchmal bereitet es Kopfschmerzen, wenn man mit eindeutigen Einschränkungen arbeitet. Hier kommt eine einfache, merkmalsbasierte Lösung, die eine elegante Möglichkeit bietet, das Problem zu vermeiden, indem einfach einmalige Felder beim Löschen vorübergehend geändert und anschließend wiederhergestellt werden. Auf diese Weise vermeiden Sie frustrierende Fehler und sorgen dafür, dass Ihre Anwendung reibungslos funktioniert, ohne eindeutige Einschränkungen in Ihrer Datenbank zu verletzen.
Wenn eines Ihrer Felder mehrsprachig gemacht wurde oder Bibliotheken wie Spatie’s Translatable nutzen, funktioniert die oben genannte Lösung in jedem dieser Fälle problemlos. Die SoftDeletes sollen Ihnen Flexibilität geben und Ihnen nicht im Weg stehen. Mit der oben genannten kleinen Korrektur vermeiden Sie die meisten Fallstricke und sorgen dafür, dass Ihre Daten aufgeräumt und Ihre Benutzer zufrieden sind.
Durch das Hinzufügen dieser Eigenschaft zu Ihren Modellen sparen Sie sich Zeit und Kopfschmerzen, insbesondere wenn Sie mit großen Datensätzen arbeiten, bei denen vorläufiges Löschen und Wiederherstellen häufige Vorgänge sind. Probieren Sie es in Ihrem Laravel-Projekt aus und Sie werden sehen, wie reibungslos es diese kniffligen Probleme mit eindeutigen Einschränkungen bewältigt!
Danke fürs Lesen! Vergessen Sie nicht, sich anzumelden, um über die neuesten Updates im Bereich Systemdesign und E-Commerce-Innovationen auf dem Laufenden zu bleiben. Viel Spaß beim Gestalten!
Wenn Sie diesen Artikel aufschlussreich fanden und mit weiteren Inhalten zu Systemdesign und Technologietrends auf dem Laufenden bleiben möchten, folgen Sie mir unbedingt auf:-
Twitter: https://twitter.com/hafiqdotcom
LinkedIn: https://www.linkedin.com/in/hafiq93
Kauf mir Kaffee: https://paypal.me/mhi9388 /
https://buymeacoffee.com/mhitech
Medium: https://medium.com/@hafiqiqmal93
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3