في لارافيل 6 عندما كنا نريد تعريف forign_key كنا نقوم بالبداية بتعريف الحقل كـ unsignedBigInteger ومن ثم نعرف key
$table->unsignedBigInteger('book_id'); $table->foreign('book_id')->references('id')->on('books');
لكن في لارافيل7 يوجد طريقة مختصرة حيث تعويض ذلك بسطر واحد
$table->foreignId('book_id')->constrained();
كذلك الحقل id في جدول books يمكننا وضع النوع id وليس bigIncrements.
إذا كنا نتعامل مع forignId مع constrained ونريد أن يكون الحقل nullable يجب تعريف nullable قبل constrained
$table->foreignId('book_id')->nullable()->constrained();//correct $table->foreignId('book_id')->constrained()->nullable();//wrong
ماذا لو كنا نستخدم forignId وتم حذف الحقل الأب؟
بالوضع الإفتراضي مثلا إذا كان لدينا كتاب وبه حقل id ويوجد عليه مراجعات لكل كتاب يربط من خلال book_id فإنه لن يقبل أن يتم حذف الكتاب، وسيعطي الخطأ التالي
#1451 - Cannot delete or update a parent row: a foreign key constraint fails (`test`.`reviews`, CONSTRAINT `reviews_book_id_foreign` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`))
لكن إذا أردنا تغيير ذلك
يجب إضافة onDelete ويجب تحديد Role حيث مجموعة أنواع من Role وهي:
NO ACTION وهي القيمة الإفتراضية، حيث إذا تم حذف الكتاب لا يتم حذف التعليقات.
RESTRICT وهي مشابهة لـ NO ACTION حيث إنه يرفض حذف الكتاب إذا كان لدية مراجعة واحدة على الأقل.
SET NULL حيث يتم وضع قيمة book_id بـ null
CASCADE عند حذف الكتاب يتم حذف التعليقات التابعة له.
$table->foreignId('book_id')->constrained()->onDelete('cascade');
كيف يمكن معرفة الملفات التي لم يتم عمل migrate لها؟
يمكننا معرفة ذلك من خلال الأمر
php artisan migrate:status
كما نلاحظ أن الملفات التي لم يتم عمل migrate لها فإن القيمة لها NO بينما التي تم عمل migrate لها قيمتها Yes.
إذا قمنا بإضافة حقل timestamp مثل reviewed_at ونريد وضع قيمة إفتراضية له بإمكاننا ببساطة إضافة useCurrent
$table->timestamp('reviewed_at')->useCurrent();
كذلك يمكن إستخدام useCurrentOnUpdate
$table->timestamp('reviewed_at')->useCurrentOnUpdate();
بالوضع الإفتراضي عند إنشاء ملف migrate فإنه يتم مسبقا تحضير الحقول id, timestamps
public function up() { Schema::create('reviews', function (Blueprint $table) { $table->id(); $table->timestamps(); });
لكن ماذا لو أردنا أن يتم إضافة softDeletes عند إنشاء أي ملف migrate
يجب تنفيذ الأمر
php artisan stub:publish
حيث يتم إنشاء مجلد جديد يحتوي على جميع stubs ويكون في المسار app/stubs ونذهب للملف migration.create.stub ونضيف الحقل softDelete
public function up() { Schema::create('{{ table }}', function (Blueprint $table) { $table->id(); $table->timestamps(); $table->softDeletes(); }); }
الأن عند تنفيذ أي أمر php artisan make:migrate create_cars_table فإن ملف migration يأتي مسبقا به الحقل softDeletes
public function up() { Schema::create('cars', function (Blueprint $table) { $table->id(); $table->timestamps(); $table->softDeletes(); }); }
وبالإمكان إعتماد نفس الطريقة إذا أردنا أن يتم إضافة حقول إفتراضيه عند إنشاء أي ملف migration.
إذا أردنا أن يتم حذف بعض الأعمدة
public function down() { Schema::create('cars', function (Blueprint $table) { $table->dropColumn('model'); $table->dropColumn('number'); }); }
لكن بالإمكان جعل الحقول التي نريد حذفها في سطر واحد
public function down() { Schema::create('cars', function (Blueprint $table) { $table->dropColumn(['model','number']); }); }
عند التراجع عن تنفيذ migrate لأخر ملف تم عمل migrate له فإننا نستخدم
php artisan migrate:rollback
لكن إذا أردنا التراجع عن أخر ثلاث ملفات تم عمل migrate لها
php artisan migrate:rollback --step=3
كذلك يمكن إستخدامها مع refresh
php artisan migrate:refresh --step=3
من المعروف أن الحقل id إذا كان autoIncrement فإنه سوف يبدأ من العدد 1، لكن إذا أردنا أن يبدأ من رقم معين مثلا 1000
public function up() { Schema::create('questions', function (Blueprint $table) { $table->id()->from(1000); }); }
للمبرمجين الذين يكرهون كتابة underscore (ـ) مثلا إذا أراد إضافة حقل add_field_to_users_table فبالإمكان وضع إسم ملف migration بين قوسين وإستخدام المسافات عوضا عن ـ
php artisan make:migration "add field to users table"
هل يمكن عمل rollback لملف معين ف migrations ؟
عاشت الايادي
ربنا يعطيك العافية
مقال رائع عاش نضال الشعب الفلسطيني
زائر
معلوماتك قيمة ومفيدة جدا .. يعطيك ألف عافية 👏