"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > Laravel SoftDelete: تجنب مشكلة القيد الفريد

Laravel SoftDelete: تجنب مشكلة القيد الفريد

تم النشر بتاريخ 2024-11-06
تصفح:257

Laravel SoftDelete: Avoiding the Unique Constraint Problem

نشأت هذه المقالة من 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();
        });
    }
}


هذه السمة تقوم بأمرين:

  • عند الحذف، فإنه يُلحق طابعًا زمنيًا بالحقل الفريد، مما يجعل الحقل فريدًا مرة أخرى دون التأثير على القيمة الأصلية. هذه الخدعة مفيدة للحفاظ على القيود الفريدة مستوفاة أثناء الحذف الناعم للسجل.
  • عند الاستعادة، يتم إزالة الطابع الزمني، واستعادة القيمة الأصلية للحقل الفريد.

كيف يعمل:

  • التعامل الفريد مع الحقل: عندما يتم حذف نموذج بهذه السمة، تهتم السمة بإلحاق طابع زمني بالحقول التي تريد الاحتفاظ بها فريدة (على سبيل المثال: البريد الإلكتروني، اسم المستخدم). وهذا يمنع حدوث تعارضات إذا حاولت إضافة سجل جديد بنفس القيم الفريدة.
  • التعامل مع الحقول القابلة للترجمة: إذا كان النموذج الخاص بك يستخدم مكتبة Spatie Translatable، فإن هذه السمة ذكية بما يكفي للتعامل مع الحقول متعددة اللغات أيضًا. فهو يبحث عن السمات القابلة للترجمة، ويضبط قيمها، ويحفظها باستخدام خدعة الطابع الزمني.
  • الاستعادة: عند استعادة سجل محذوف بشكل بسيط، تقوم السمة بإزالة الطابع الزمني من الحقول الفريدة، مما يعيد الحقل إلى قيمته الأصلية.

تطبيق السمة على النموذج الخاص بك

إليك كيفية تطبيق هذه السمة في نموذج 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

بيان الافراج تم نشر هذه المقالة على: https://dev.to/afiqiqmal/laravel-softdelete-avoiding-the-unique-constraint-problem-8k2?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3