„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Laravel SoftDelete: Vermeidung des Unique-Constraint-Problems

Laravel SoftDelete: Vermeidung des Unique-Constraint-Problems

Veröffentlicht am 06.11.2024
Durchsuche:208

Laravel SoftDelete: Avoiding the Unique Constraint Problem

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.

Das Problem verstehen

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.

Die Lösung: Verwendung einer Eigenschaft zur Vermeidung doppelter Einschränkungen

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:

  • Beim Löschen wird ein Zeitstempel an das eindeutige Feld angehängt, wodurch das Feld im Wesentlichen wieder eindeutig wird, ohne dass sich dies auf den ursprünglichen Wert auswirkt. Dieser Trick ist nützlich, um eindeutige Einschränkungen einzuhalten, während der Datensatz vorläufig gelöscht wird.
  • Bei der Wiederherstellung wird der Zeitstempel entfernt und der ursprüngliche Wert des eindeutigen Felds wiederhergestellt.

So funktioniert es:

  • Eindeutige Feldbehandlung: Immer wenn ein Modell mit dieser Eigenschaft gelöscht wird, sorgt die Eigenschaft dafür, dass ein Zeitstempel an die Felder angehängt wird, die eindeutig bleiben sollen (Beispiel: E-Mail, Benutzername). Dies verhindert Konflikte, wenn Sie versuchen, einen neuen Datensatz mit denselben eindeutigen Werten hinzuzufügen.
  • Umgang mit übersetzbaren Feldern: Wenn Ihr Modell die Spatie Translatable-Bibliothek verwendet, ist diese Funktion intelligent genug, um auch mehrsprachige Felder zu verarbeiten. Es sucht nach den übersetzbaren Attributen, passt ihre Werte an und speichert sie mit dem Zeitstempel-Trick.
  • Wiederherstellung: Wenn Sie einen vorläufig gelöschten Datensatz wiederherstellen, entfernt die Eigenschaft den Zeitstempel aus den eindeutigen Feldern und stellt das Feld auf seinen ursprünglichen Wert zurück.

Anwenden der Eigenschaft auf Ihr Modell

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 .

Warum funktioniert dieser Ansatz?

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.


Letzte Gedanken

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

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/afiqiqmal/laravel-softdelete-avoiding-the-unique-constraint-problem-8k2?1 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

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