Источник этой статьи: https://medium.com/@hafiqiqmal93/laravel-softdelete-avoiding-the-unique-constraint-problem-45381d9745a0
Если вы какое-то время используете Laravel, особенно когда проекты связаны с целостностью данных, скорее всего, вы уже сталкивались с функцией SoftDelete. Довольно полезно, поскольку вы можете «удалять» записи, не удаляя их из базы данных. Laravel просто добавляет метку времени delete_at, чтобы отметить его как удаленный, но он остается в системе. Это все хорошо для сохранения исторических данных, но при этом возникает одна потенциально неприятная проблема — что происходит с уникальными ограничениями при восстановлении обратимо удаленных записей?
Это становится проблемой, когда вы хотите восстановить запись, которая уже имеет, например, уникальный адрес электронной почты или имя пользователя в базе данных. Laravel просто выдаст ошибку и остановит процесс. К счастью, есть простой способ избежать этой проблемы.
Давайте рассмотрим решение, использующее особенность, которая поможет вам обойти уникальные ограничения при использовании SoftDelete в Laravel.
Давайте рассмотрим простой пример. Представьте, что у вас есть таблица пользователей с полем электронной почты, которое должно быть уникальным:
Schema::create('users', function (Blueprint $table) { $table->string('email')->unique(); $table->softDeletes(); });
Если вы мягко удалите пользователя с адресом электронной почты [email protected], а затем создадите нового пользователя с тем же адресом электронной почты, Laravel будет жаловаться на уникальное ограничение в поле адреса электронной почты, выдавая ошибку. В той же ситуации, когда вы пытаетесь восстановить удаленного пользователя, Laravel также будет жаловаться на уникальное ограничение поля электронной почты и выдавать ту же ошибку.
Это становится головной болью, особенно при работе с большими системами, где восстановление записей является обычной задачей.
Чтобы предотвратить это, мы можем временно изменить значения уникальных полей при обратимом удалении записи и восстановить исходные значения при возвращении записи. Таким образом, база данных не нарушает ограничение уникальности во время обратимого удаления или восстановления.
Трайт Laravel — отличный способ инкапсулировать эту функциональность. Вот черта, которую мы можем использовать для решения этой проблемы:
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(); }); } }
Эта черта выполняет несколько функций:
Вот как вы можете применить эту черту в своей модели Laravel:
class User extends Model { use SoftDeletes, AvoidDuplicateConstraintSoftDelete; // Specify which columns should avoid the unique constraint issue public function getDuplicateAvoidColumns(): array { return ['email', 'username']; } }
Добавив признак **AvoidDuplateConstraintSoftDelete** в свою модель и указав, какие столбцы должны избегать конфликтов уникальных ограничений (например, email и имя пользователя), вы можете легко предотвратить эти проблемы. .
Это означает, что в случае обратимого удаления записи это не вызовет конфликта с дальнейшими операциями из-за некоторых уникальных ограничений. Другими словами, таким образом вы сможете, добавив временную метку к уникальным полям, сделать запись «скрытой» для базы данных с точки зрения уникальности, но при этом ее можно будет восстановить при необходимости.
Это весьма полезно, когда вы имеете дело с большой базой данных и восстановление записей является довольно распространенным явлением. Вам не придется каждый раз сталкиваться с ошибкой «дубликат записи», когда вы добавляете обратимо удаленного пользователя или любую другую модель.
Самая полезная вещь в Laravel — это SoftDelete, но иногда он доставляет головную боль при работе с уникальными ограничениями. Вот простое решение, основанное на признаках, которое даст элегантный способ избежать проблемы, просто временно изменяя уникальные поля при удалении и последующем восстановлении. Таким образом, вы избежите досадных ошибок и позволите вашему приложению работать бесперебойно, не нарушая уникальных ограничений в вашей базе данных.
Если какое-либо из ваших полей сделано многоязычным или используются такие библиотеки, как Spatie's Translatable, приведенное выше решение будет работать без проблем в каждом из этих случаев. SoftDeletes предназначены для того, чтобы дать вам гибкость, а не мешать вам. Внеся вышеуказанное незначительное исправление, вы избежите большинства ошибок, сохраните свои данные в порядке, а ваши пользователи будут довольны.
Добавив эту особенность в свои модели, вы сэкономите время и избавитесь от головной боли, особенно если вы имеете дело с большими наборами данных, где мягкое удаление и восстановление являются частыми операциями. Попробуйте его в своем проекте Laravel, и вы увидите, насколько гладко он справляется с этими сложными уникальными проблемами ограничений!
Спасибо, что читаете! Не забудьте подписаться, чтобы быть в курсе последних обновлений в области системного проектирования и инноваций в электронной коммерции. Приятного проектирования!
Если эта статья показалась вам познавательной и вы хотите быть в курсе новых новостей о дизайне систем и тенденциях в области технологий, обязательно подпишитесь на меня :-
Твиттер: https://twitter.com/hafiqdotcom
LinkedIn: https://www.linkedin.com/in/hafiq93
Купи мне кофе: https://paypal.me/mhi9388/
https://buymeacoffee.com/mhitech
Средний: https://medium.com/@hafiqiqmal93
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3