نشأت هذه المقالة من https://medium.com/@hafiqiqmal93/laravel-softdelete-avoiding-the-unique-constraint-problem-45381d9745a0
في حال كنت تستخدم Laravel لفترة من الوقت، خاصة عندما تتضمن المشاريع تكامل البيانات، فمن المرجح أنك واجهت بالفعل ميزة SoftDelete. مفيد جدًا لأنه يمكنك "حذف" السجلات دون إخراجها من قاعدة البيانات. ما يفعله Laravel هو مجرد إضافة طابع زمني محذوف_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']; } }
من خلال إضافة السمة **AvoidDuplicateConstraintSoftDelete** إلى النموذج الخاص بك وتحديد الأعمدة التي تحتاج إلى تجنب تعارضات القيود الفريدة (مثل البريد الإلكتروني واسم المستخدم)، يمكنك بسهولة منع هذه المشكلات .
ما يعنيه ذلك هو أنه في حالة وجود سجل حذف بسيط، فلن يتسبب ذلك في حدوث تعارض مع العمليات الإضافية بسبب بعض القيود الفريدة. أو بمعنى آخر، بهذه الطريقة ستتمكن، من خلال إلحاق الطابع الزمني بالحقول الفريدة، من جعل السجل "مخفيًا" لقاعدة البيانات من حيث التفرد ولكن لا يزال قابلاً للاسترداد عند الحاجة.
يعد هذا مفيدًا جدًا عندما تتعامل مع قاعدة بيانات كبيرة وتكون استعادة السجلات أمرًا شائعًا جدًا. لن تضطر إلى التعامل في كل مرة مع خطأ "الإدخال المكرر" عندما تقوم بإحضار مستخدم محذوف مبدئيًا أو أي نموذج آخر.
الشيء الأكثر فائدة في Laravel هو SoftDelete، لكنه يسبب أحيانًا صداعًا أثناء العمل بقيود فريدة. هنا يأتي حل بسيط قائم على السمات والذي سيوفر طريقة أنيقة لتجنب المشكلة، فقط عن طريق التغييرات المؤقتة للحقول الفريدة عند الحذف والاستعادة بعد ذلك. بهذه الطريقة سوف تتجنب الأخطاء المحبطة وتسمح لتطبيقك بالعمل بسلاسة دون كسر القيود الفريدة في قاعدة البيانات الخاصة بك.
إذا تم جعل أي من حقولك متعدد اللغات أو الاستفادة من مكتبات مثل Spatie’s Translatable، فسيعمل الحل أعلاه دون مشاكل في كل حالة من هذه الحالات. تهدف SoftDeletes إلى منحك المرونة، وليس أن تعترض طريقك. مع تطبيق الإصلاح البسيط أعلاه، ستتجنب معظم المخاطر وتحافظ على بياناتك مرتبة وتسعد المستخدمين.
بإضافة هذه السمة إلى نماذجك، ستوفر على نفسك الوقت والمتاعب، خاصة إذا كنت تتعامل مع مجموعات بيانات كبيرة حيث تكون عمليات الحذف البسيط والاستعادة عمليات متكررة. جربه في مشروع Laravel الخاص بك، وسترى مدى سلاسة تعامله مع مشكلات القيود الفريدة والصعبة!
شكرا لقرائتكم! لا تنس الاشتراك لتبقى على اطلاع بآخر التحديثات في تصميم النظام وابتكارات التجارة الإلكترونية. تصميم سعيد!
إذا وجدت هذه المقالة مفيدة وترغب في البقاء على اطلاع دائم بالمزيد من المحتوى حول تصميم النظام واتجاهات التكنولوجيا، فتأكد من متابعتي على :-
تويتر: https://twitter.com/hafiqdotcom
لينكد إن: 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