recent
أخبار ساخنة

إنشاء قاعدة البيانات والجداول وإدارتها Database و Migrations في Laravel

Database وMigrations في Laravel – إنشاء قاعدة البيانات والجداول وإدارتها

إنشاء قاعدة البيانات والجداول وإدارتها Database وMigrations

بعد أن تعلّمنا في الدروس السابقة أساسيات Laravel، مثل Routing و Controllers و Blade و Requests وValidation، أصبحنا الآن جاهزين للانتقال إلى جزء مهم جدًا من أي تطبيق ويب: قاعدة البيانات Database.

معظم التطبيقات التي نبنيها في Laravel تحتاج إلى تخزين البيانات بشكل دائم. فإذا كنا نبني موقع مقالات، فنحن نحتاج إلى حفظ عناوين المقالات ومحتواها. وإذا كنا نبني متجرًا إلكترونيًا، فنحتاج إلى تخزين المنتجات والعملاء والطلبات. وإذا كنا نبني نظامًا لإدارة المستخدمين، فنحتاج إلى جداول المستخدمين والصلاحيات والبيانات المرتبطة بهم.

وهنا يأتي دور قاعدة البيانات، ثم تأتي Migrations في Laravel لتساعدنا على إنشاء بنية قاعدة البيانات وإدارتها بطريقة منظمة وقابلة للتتبع.

في هذا الدرس سنتعلم كيفية إعداد قاعدة البيانات، وفهم ملف .env، وإنشاء الجداول باستخدام Migrations، وتشغيلها والتراجع عنها، بالإضافة إلى التعرف على أهم أنواع الأعمدة والفهارس والمفاتيح الأجنبية، ثم سنبني مثالًا عمليًا لجدول articles.

ما هي قاعدة البيانات Database؟

قاعدة البيانات هي المكان الذي يتم فيه تخزين بيانات التطبيق بطريقة منظمة.

بدلًا من حفظ البيانات داخل ملفات نصية أو متغيرات PHP، يمكننا استخدام نظام متخصص مثل:

  • MySQL
  • MariaDB
  • PostgreSQL
  • SQLite

وغيرها من أنظمة قواعد البيانات التي يدعمها Laravel.

على سبيل المثال، إذا كان لدينا موقع مقالات، يمكن أن يكون لدينا جدول باسم:

articles

ويحتوي الجدول على أعمدة مثل:

id
title
slug
content
status
created_at
updated_at

وبذلك يمكن لكل مقال أن يكون عبارة عن سجل Record داخل هذا الجدول.

الفكرة الأساسية هي:

Laravel Application
       ↓
Database Connection
       ↓
Database
       ↓
Tables
       ↓
Rows / Records

لكن Laravel لا يجبرك على كتابة SQL يدويًا لإنشاء كل جدول. وهنا تظهر أهمية Migrations.

ما هي Migrations في Laravel؟

يمكننا اعتبار Migration بمثابة نسخة تحكم Version Control لهيكل قاعدة البيانات.

بدل أن تقول لزميلك:

أنشئ جدول articles يدويًا، وأضف هذه الأعمدة، ثم أضف هذا المفتاح...

يمكنك إنشاء Migration تحتوي على هذه التعليمات، ثم يستطيع أي شخص في المشروع تشغيل:

php artisan migrate

وسيتم إنشاء الجداول حسب التعريف الموجود في ملفات Migration.

وهذا يجعل قاعدة البيانات جزءًا من كود المشروع ويمكن مشاركتها عبر Git مع بقية ملفات التطبيق.

توثيق Laravel يصف الـ migrations بأنها تشبه نظام Version Control لقاعدة البيانات، لأنها تسمح للفريق بتعريف ومشاركة مخطط قاعدة البيانات وتعديلاته بطريقة منظمة.

أين توجد ملفات Migrations؟

ستجد ملفات Migration داخل:

database/migrations

وعند فتح المشروع قد تجد ملفات مثل:

database/
├── factories/
├── migrations/
│   ├── xxxx_xx_xx_xxxxxx_create_users_table.php
│   ├── xxxx_xx_xx_xxxxxx_create_cache_table.php
│   └── xxxx_xx_xx_xxxxxx_create_jobs_table.php
└── seeders/

كل Migration لها اسم يحتوي على Timestamp.

مثل:

2026_01_15_120000_create_articles_table.php

وجود التاريخ والوقت في اسم الملف يساعد Laravel على معرفة ترتيب تنفيذ الـ migrations.

إعداد قاعدة البيانات في Laravel

قبل إنشاء الجداول، يجب أن يعرف Laravel قاعدة البيانات التي سيستخدمها التطبيق.

عادة يتم تحديد إعدادات قاعدة البيانات داخل ملف:

.env

وهذا الملف موجود في جذر مشروع Laravel.

في Laravel الحديث قد يكون المشروع الجديد معدًا افتراضيًا لاستخدام SQLite، ويمكنك استخدام قاعدة بيانات أخرى مثل MySQL أو PostgreSQL إذا كان هذا هو ما تحتاجه. توثيق Laravel 13 يوضح أن إعدادات الاتصال يتم تحديدها من خلال متغيرات البيئة في .env.

استخدام SQLite

SQLite خيار بسيط جدًا للمشاريع التعليمية والتجارب المحلية.

في مشروع Laravel يمكن أن يكون الاتصال مثل:

DB_CONNECTION=sqlite

وفي هذه الحالة يستخدم Laravel ملف قاعدة بيانات SQLite داخل المشروع.

في المشاريع الجديدة، يمكن أن ينشئ Laravel ملف:

database/database.sqlite

بحسب طريقة إنشاء المشروع وإعداداته.

ميزة SQLite أنه لا يحتاج إلى تشغيل خادم MySQL منفصل، ولذلك هو مناسب جدًا عندما تتعلم Laravel أو تبني مشروعًا صغيرًا.

استخدام MySQL

إذا أردت استخدام MySQL، يمكن أن تكون إعدادات .env مثل:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

يجب أن تتوافق هذه القيم مع إعدادات MySQL الموجودة على جهازك.

مثلًا:

DB_DATABASE=laravel

تعني أن Laravel سيحاول الاتصال بقاعدة بيانات اسمها:

laravel

ويجب أن تكون قاعدة البيانات موجودة بالفعل في MySQL.

بعد إعداد الاتصال، يمكنك تشغيل:

php artisan migrate

لتنفيذ الـ migrations وإنشاء الجداول.

لماذا نستخدم ملف .env؟

من الأخطاء الشائعة أن تضع بيانات الاتصال بقاعدة البيانات مباشرة داخل ملفات المشروع.

مثلًا لا يُفضل أن تكتب كلمة المرور داخل Controller:

>$password = 'mypassword';

بدلًا من ذلك تستخدم:

DB_PASSWORD=mypassword

ثم يعتمد Laravel على إعدادات البيئة.

وهذا مفيد لأن إعدادات جهاز المطور قد تختلف عن إعدادات السيرفر.

مثلًا:

Developer Machine
DB_DATABASE=laravel_dev

Testing Server
DB_DATABASE=laravel_testing

Production Server
DB_DATABASE=laravel_production

وبذلك لا تحتاج إلى تغيير كود التطبيق نفسه عند تغيير البيئة.

كما أن ملف .env قد يحتوي على بيانات حساسة، ولذلك يجب عدم رفعه إلى مستودع Git العام. توثيق Laravel يحذر من وضع .env في Source Control لأن ذلك قد يؤدي إلى كشف بيانات حساسة.

إنشاء أول Migration

لنفرض أننا نريد إنشاء جدول للمقالات.

يمكننا تنفيذ:

php artisan make:migration create_articles_table

سيقوم Laravel بإنشاء ملف جديد داخل:

database/migrations

وسيكون الاسم شبيهًا بـ:

2026_09_17_120000_create_articles_table.php

التاريخ والوقت في الاسم يختلفان حسب وقت إنشاء الملف.

فهم ملف Migration

عند فتح Migration ستجد بنية مشابهة:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        //
    }

    public function down(): void
    {
        //
    }
};

لدينا هنا وظيفتان أساسيتان:

up()

و:

down()

ما وظيفة up()؟

الدالة:

up()

تحتوي على التغييرات التي نريد تطبيقها على قاعدة البيانات.

مثلًا إنشاء جدول:

public function up(): void
{
    Schema::create('articles', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

هذا يعني أننا نريد إنشاء جدول اسمه:

articles

وإضافة مجموعة من الأعمدة إليه.

ما وظيفة down()؟

الدالة:

down()

تحتوي على العملية العكسية.

إذا أنشأنا جدول:

articles

في up()، فمن الطبيعي أن تقوم down() بحذفه:

public function down(): void
{
    Schema::dropIfExists('articles');
}

وبذلك يستطيع Laravel التراجع عن Migration عند استخدام أوامر الـ rollback.

إنشاء جدول Articles كامل

لننشئ جدولًا بسيطًا للمقالات:

public function up(): void
{
    Schema::create('articles', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug')->unique();
        $table->text('content');
        $table->boolean('is_published')->default(false);
        $table->timestamps();
    });
}

والـ down():

public function down(): void
{
    Schema::dropIfExists('articles');
}

الآن أصبح لدينا جدول يمكن استخدامه لتخزين المقالات.

فهم $table->id()

السطر:

$table->id();

ينشئ عمودًا يسمى:

id

ويستخدم عادة كمفتاح أساسي Primary Key للجدول.

مثلًا:

id
1
2
3
4

كل مقال يمكن أن يكون له ID مختلف.

إنشاء أعمدة نصية

لإنشاء عمود نصي قصير:

$table->string('title');

مثل:

Laravel للمبتدئين

ويمكن تحديد طول العمود عند الحاجة:

$table->string('title', 150);

لكن في كثير من الحالات يكفي استخدام:

$table->string('title');

استخدام text()

إذا كان لدينا نص طويل مثل محتوى المقال، يمكن استخدام:

$table->text('content');

وهذا مناسب للمحتوى الأطول من البيانات النصية القصيرة.

مثال:

$table->text('description');
$table->text('content');

الأرقام

يمكن أن نحتاج إلى تخزين أرقام.

مثلًا:

$table->integer('views');

أو:

$table->unsignedInteger('views');

ويمكن أيضًا استخدام أنواع أخرى حسب الحاجة مثل:

$table->bigInteger('number');

لكن اختيار نوع العمود يجب أن يعتمد على طبيعة البيانات التي ستخزنها.

Boolean

إذا كانت لدينا قيمة نعم/لا، يمكن استخدام:

$table->boolean('is_published');

مثل:

true
false

ويمكن إعطاؤها قيمة افتراضية:

$table->boolean('is_published')->default(false);

وهذا يعني أن المقال الجديد سيكون غير منشور افتراضيًا.

التاريخ والوقت

يمكن إنشاء أعمدة للتاريخ والوقت باستخدام:

$table->date('published_at');

أو:

$table->dateTime('published_at');

والفرق أن date يخزن التاريخ، بينما dateTime يخزن التاريخ والوقت.

timestamps()

من أكثر الأسطر استخدامًا:

$table->timestamps();

وهو يضيف عمودين:

created_at
updated_at

الأول يحدد وقت إنشاء السجل.

والثاني يحدد وقت آخر تعديل عليه.

مثال:

id | title              | created_at          | updated_at
1  | تعلم Laravel       | 2026-09-17 ...      | 2026-09-17 ...

وهذان العمودان مهمان جدًا في تطبيقات Laravel.

nullable()

أحيانًا يكون لدينا عمود اختياري.

مثلًا:

$table->string('subtitle')->nullable();

هذا يعني أن subtitle يمكن أن تكون قيمته:

NULL

بدل أن تكون مطلوبة دائمًا.

مثال عملي:

$table->string('title');
$table->string('subtitle')->nullable();

هنا:

  • title مطلوب.

  • subtitle اختياري.

وهذا يتوافق أيضًا مع مفهوم nullable الذي تعرفنا عليه في درس Validation، لكن يجب الانتباه إلى أن nullable في قاعدة البيانات يتعلق بالسماح بتخزين NULL، بينما قاعدة nullable في Validation تتعلق بكيفية التحقق من البيانات القادمة إلى التطبيق.

default()

يمكننا إعطاء العمود قيمة افتراضية:

$table->boolean('is_published')->default(false);

أو:

$table->integer('views')->default(0);

إذا أنشأنا سجلًا ولم نرسل قيمة views، يمكن أن تكون القيمة الافتراضية:

0

unique()

إذا أردنا منع تكرار قيمة معينة، يمكننا استخدام:

$table->string('slug')->unique();

هذا مهم جدًا في المقالات.

فإذا كان لدينا:

laravel-routing

لا نريد أن يكون هناك مقالان بنفس الـ slug.

وبذلك تصبح قيمة slug فريدة داخل الجدول.

ما هي Indexes؟

الـ Index هو فهرس يساعد قاعدة البيانات على البحث والتعامل مع البيانات بكفاءة في حالات معينة.

يمكن إنشاء Index مثل:

$table->index('status');

أو:

$table->index(['status', 'created_at']);

ليس معنى ذلك أن علينا إضافة Index إلى كل عمود.

يجب استخدام الفهارس بناءً على احتياجات التطبيق والاستعلامات التي يتم تنفيذها بشكل متكرر.

مثلًا إذا كان التطبيق يبحث كثيرًا عن المقالات حسب:

status

فقد يكون من المفيد إنشاء Index لهذا العمود.

Foreign Keys والمفاتيح الأجنبية

في التطبيقات الحقيقية، غالبًا لا تكون الجداول منفصلة عن بعضها.

لنفترض أن لدينا:

users
articles

وكل مقال ينتمي إلى مستخدم.

يمكن أن يحتوي جدول articles على:

user_id

وهذا العمود يمكن أن يرتبط بـ:

users.id

مثال:

$table->foreignId('user_id')->constrained();

وهنا نخبر قاعدة البيانات بأن:

articles.user_id

مرتبط بمفتاح في جدول المستخدمين.

يمكن أيضًا تحديد ما يحدث عند حذف المستخدم:

$table->foreignId('user_id')
    ->constrained()
    ->cascadeOnDelete();

وبهذا يمكن إعداد علاقة في قاعدة البيانات بحيث يؤدي حذف المستخدم إلى حذف السجلات المرتبطة به وفق هذا القيد.

مثال عملي: Articles مع Users

يمكن أن يكون Migration للمقالات مثل:

public function up(): void
{
    Schema::create('articles', function (Blueprint $table) {
        $table->id();

        $table->foreignId('user_id')
            ->constrained()
            ->cascadeOnDelete();

        $table->string('title');
        $table->string('slug')->unique();
        $table->text('content');
        $table->boolean('is_published')->default(false);
        $table->timestamp('published_at')->nullable();

        $table->timestamps();
    });
}

لدينا الآن:

articles
│
├── id
├── user_id
├── title
├── slug
├── content
├── is_published
├── published_at
├── created_at
└── updated_at

والـ user_id يربط المقال بالمستخدم.

سنتعمق أكثر في العلاقات بين Models والجداول في درس العلاقات القادم، لكن من المهم أن تفهم الآن أساس فكرة Foreign Key.

تشغيل Migrations

بعد إنشاء Migration، لن يتم إنشاء الجدول تلقائيًا لمجرد إنشاء الملف.

نحتاج إلى تشغيل:

php artisan migrate

سيقرأ Laravel الـ migrations التي لم يتم تنفيذها، ثم يقوم بتطبيقها على قاعدة البيانات.

إذا كانت Migration الخاصة بـ articles صحيحة، سيظهر الجدول في قاعدة البيانات.

كيف يعرف Laravel ما تم تنفيذه؟

Laravel يحتفظ بسجل للـ migrations التي تم تنفيذها.

وبذلك عندما تشغل:

php artisan migrate

مرة أخرى، لا يقوم Laravel بإعادة إنشاء كل الجداول من البداية، بل يعرف ما تم تنفيذه وما لم يتم تنفيذه.

وهذه واحدة من أهم فوائد نظام migrations.

التراجع عن آخر Migration

إذا أردت التراجع عن آخر مجموعة من الـ migrations التي تم تنفيذها، يمكنك استخدام:

php artisan migrate:rollback

توثيق Laravel يوضح أن rollback يتراجع عن آخر Batch من migrations، وقد يحتوي هذا الـ batch على أكثر من ملف Migration.

يمكنك أيضًا تحديد عدد الخطوات:

php artisan migrate:rollback --step=1

أو:

php artisan migrate:rollback --step=5

migrate:reset

هناك أمر آخر:

php artisan migrate:reset

يؤدي إلى التراجع عن جميع الـ migrations.

هذا يختلف عن:

php artisan migrate:rollback

لأن rollback يتعامل مع آخر Batch، بينما reset يتراجع عن جميع الـ migrations.

migrate:refresh

يمكن استخدام:

php artisan migrate:refresh

وهو يقوم بالتراجع عن الـ migrations ثم تشغيلها من جديد.

أي أن الفكرة بشكل مبسط:

Rollback
   ↓
Migrate Again

ويمكن تشغيله مع Seeders أيضًا:

php artisan migrate:refresh --seed

توثيق Laravel يوضح أن refresh يعيد تشغيل migrations بعد التراجع عنها.

migrate:fresh

من الأوامر المهمة أيضًا:

php artisan migrate:fresh

هذا الأمر يقوم بحذف جميع الجداول ثم تشغيل جميع الـ migrations من جديد.

ويمكن تشغيله مع Seeders:

php artisan migrate:fresh --seed

لكن انتبه جدًا:

migrate:fresh

يمكن أن يحذف البيانات الموجودة في قاعدة البيانات.

لذلك استخدمه بحذر، وخصوصًا لا تستخدمه على قاعدة بيانات Production بدون فهم كامل لما سيحدث.

الفرق بين أهم أوامر Migrations

يمكنك حفظ الفرق بهذا الشكل:

الأمرالوظيفة
php artisan migrateتنفيذ الـ migrations الجديدة
php artisan migrate:rollbackالتراجع عن آخر Batch
php artisan migrate:resetالتراجع عن جميع الـ migrations
php artisan migrate:refreshRollback ثم تشغيل migrations من جديد
php artisan migrate:freshحذف الجداول ثم إعادة إنشائها
php artisan migrate:fresh --seedحذف الجداول وإعادة إنشائها وتشغيل Seeders

هذه الأوامر مهمة جدًا أثناء تطوير التطبيقات.

تعديل جدول موجود

لنفترض أنك أنشأت جدول:

articles

ثم اكتشفت أنك تحتاج إلى إضافة:

excerpt

لا يفضل أن تذهب وتعدل Migration قديمة تم تشغيلها بالفعل على قواعد بيانات الفريق.

بدلًا من ذلك، أنشئ Migration جديدة.

مثلًا:

php artisan make:migration add_excerpt_to_articles_table

ثم داخل Migration:

public function up(): void
{
    Schema::table('articles', function (Blueprint $table) {
        $table->text('excerpt')->nullable();
    });
}

وفي down():

public function down(): void
{
    Schema::table('articles', function (Blueprint $table) {
        $table->dropColumn('excerpt');
    });
}

ثم:

php artisan migrate

وبذلك تمت إضافة العمود إلى الجدول.

هذه الطريقة مهمة جدًا في المشاريع الجماعية؛ لأن كل تغيير في بنية قاعدة البيانات يصبح Migration جديدة يمكن تتبعها ومشاركتها مع الفريق.

وتوصي مواد Laravel التعليمية باستخدام migrations كطريقة منظمة لتغيير بنية قاعدة البيانات بدل تعديل التاريخ القديم عشوائيًا.

حذف عمود

إذا أردت حذف عمود:

$table->dropColumn('excerpt');

مثال:

Schema::table('articles', function (Blueprint $table) {
    $table->dropColumn('excerpt');
});

ثم:

php artisan migrate

إعادة تسمية عمود

يمكن إعادة تسمية عمود باستخدام:

$table->renameColumn('title', 'name');

لكن يجب أن تكون حذرًا عند تغيير أسماء الأعمدة في التطبيقات التي تحتوي على كود يعتمد على الاسم القديم.

فإذا كان لديك Controller يستخدم:

$article->title

ثم غيرت العمود إلى:

name

ستحتاج أيضًا إلى تحديث الكود الذي يعتمد على title.

حذف جدول

لحذف جدول:

Schema::dropIfExists('articles');

لكن عادة نضع هذا في:

down()

حتى يستطيع Laravel التراجع عن Migration.

مثال عملي كامل

لنقم الآن ببناء Migration حقيقية لجدول مقالات.

أولًا:

php artisan make:migration create_articles_table

ثم:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();

            $table->foreignId('user_id')
                ->constrained()
                ->cascadeOnDelete();

            $table->string('title');
            $table->string('slug')->unique();
            $table->text('excerpt')->nullable();
            $table->longText('content');

            $table->boolean('is_published')
                ->default(false);

            $table->timestamp('published_at')
                ->nullable();

            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('articles');
    }
};

بعد ذلك:

php artisan migrate

أصبح لدينا جدول مقالات يحتوي على:

id
user_id
title
slug
excerpt
content
is_published
published_at
created_at
updated_at

وهذا الجدول يمكن أن يكون أساسًا ممتازًا لنظام المقالات الذي سنبنيه تدريجيًا خلال دروس Laravel القادمة.

ما العلاقة بين Migrations وModels؟

حتى الآن نحن نتعامل مع بنية قاعدة البيانات.

لكن ماذا لو أردنا داخل Laravel أن نقول:

Article::all();

أو:

Article::find(1);

هنا ندخل في موضوع مهم جدًا وهو:

Eloquent ORM وModels

الـ Migration تحدد لنا شكل الجدول.

أما الـ Model فيمثل البيانات والتعامل معها من داخل التطبيق.

بشكل مبسط:

Migration
    ↓
Database Table
    ↓
Model
    ↓
Controller
    ↓
View

مثال:

create_articles_table.php
          ↓
      articles
          ↓
       Article
          ↓
 ArticleController
          ↓
   articles/index.blade.php

وسنتعلم في الدرس القادم كيف ننشئ Model ونتعامل مع البيانات باستخدام Eloquent.

أخطاء شائعة عند استخدام Migrations

تشغيل migrate بدون إعداد قاعدة البيانات

إذا كان لديك MySQL ولم تقم بإنشاء قاعدة البيانات أو كانت بيانات .env غير صحيحة، قد تحصل على خطأ في الاتصال.

راجع:

DB_CONNECTION
DB_HOST
DB_PORT
DB_DATABASE
DB_USERNAME
DB_PASSWORD

تعديل Migration قديمة بعد تشغيلها

إذا كانت Migration قديمة وتم تنفيذها، لا تعتمد على تعديلها فقط وانتظار أن يكتشف Laravel التغيير.

أنشئ Migration جديدة لتعديل الجدول.

استخدام migrate:fresh بدون الانتباه

الأمر:

php artisan migrate:fresh

يحذف الجداول ثم يعيد إنشاءها.

لذلك يمكن أن تفقد البيانات الموجودة في قاعدة البيانات. Laravel يحذر من استخدام هذا الأمر بحذر خصوصًا مع قواعد البيانات المشتركة.

نسيان تشغيل migrate

قد تكتب Migration كاملة ثم تحاول استخدام الجدول، لكنك نسيت:

php artisan migrate

في هذه الحالة الجدول لن يكون موجودًا في قاعدة البيانات.

الخلط بين Validation وقاعدة البيانات

في الدرس السابق استخدمنا:

$request->validate([
    'title' => ['required', 'string'],
]);

هذا يتحقق من البيانات القادمة من المستخدم.

أما:

$table->string('title');

فهذا يحدد شكل العمود في قاعدة البيانات.

إذن:

Validation
    ↓
هل البيانات القادمة صحيحة؟

Migration
    ↓
كيف سيكون شكل قاعدة البيانات؟

كلاهما مهم، لكن لكل واحد وظيفة مختلفة.

أفضل ممارسات Migrations

عند العمل على مشروع Laravel حقيقي، حاول الالتزام بمجموعة من الممارسات:

1 - استخدم أسماء واضحة

بدل:

php artisan make:migration change_table

استخدم اسمًا يوضح ما يحدث:

php artisan make:migration add_excerpt_to_articles_table

أو:

php artisan make:migration create_articles_table

2 - اجعل كل Migration لها هدف واضح

لا تضع عشرات التغييرات غير المرتبطة في Migration واحدة.

من الأفضل أن تكون كل Migration مسؤولة عن تغيير واضح.

3 - لا تضع البيانات داخل Migration

الـ Migration مخصصة بشكل أساسي لبنية قاعدة البيانات.

أما إدخال البيانات التجريبية فيمكن التعامل معه من خلال:

Seeders
Factories

وسنتعلم ذلك لاحقًا.

احتفظ بالـ Migrations في Git

Migration جزء من المشروع، ولذلك يجب أن تكون ضمن ملفات المشروع التي يتم تتبعها في Git.

إذا أضاف أحد أعضاء الفريق Migration جديدة، يمكن لباقي الفريق الحصول عليها وتشغيل:

php artisan migrate

لتحديث قاعدة البيانات المحلية.

تمرين عملي

قبل الانتقال إلى الدرس القادم، حاول تنفيذ التمرين التالي بنفسك.

أنشئ Migration باسم:

php artisan make:migration create_categories_table

واجعل جدول categories يحتوي على:

id
name
slug
description
is_active
created_at
updated_at

بحيث:

  • id مفتاح أساسي.
  • name نص قصير.
  • slug نص فريد.
  • description نص اختياري.
  • is_active قيمة Boolean.
  • القيمة الافتراضية لـ is_active تكون true.
  • استخدم timestamps().

ثم شغّل:

php artisan migrate

بعد ذلك جرّب:

php artisan migrate:rollback

ثم أعد تشغيل:

php artisan migrate

بهذا ستتعرف عمليًا على دورة حياة Migration.

ماذا تعلمنا في هذا الدرس؟

في هذا الدرس تعرفنا على أساسيات قواعد البيانات في Laravel، وتعلمنا أن قاعدة البيانات هي المكان الذي يتم فيه تخزين بيانات التطبيق بشكل دائم.

تعلمنا أيضًا أن Laravel يستخدم ملف:

.env

لتحديد إعدادات البيئة، ومنها إعدادات الاتصال بقاعدة البيانات.

ثم تعرفنا على Migrations الموجودة داخل:

database/migrations

وتعلمنا إنشاء Migration باستخدام:

php artisan make:migration create_articles_table

وتعرفنا على:

up()

لتطبيق التغيير، و:

down()

للتراجع عنه.

كما تعلمنا إنشاء الأعمدة باستخدام:

$table->id();
$table->string();
$table->text();
$table->boolean();
$table->integer();
$table->timestamp();
$table->timestamps();

وتعرفنا على:

nullable()
default()
unique()
index()
foreignId()
constrained()
cascadeOnDelete()

ثم تعلمنا أهم أوامر Migration:

php artisan migrate
php artisan migrate:rollback
php artisan migrate:reset
php artisan migrate:refresh
php artisan migrate:fresh

وأصبح لدينا الآن تصور واضح عن كيفية بناء هيكل قاعدة البيانات وإدارته داخل Laravel.

الآن أصبح لدينا جدول في قاعدة البيانات، لكننا ما زلنا بحاجة إلى طريقة سهلة للتعامل معه من داخل Laravel.

فبدلًا من كتابة SQL يدويًا في كل مرة نريد فيها قراءة أو إضافة أو تعديل بيانات، يوفر Laravel نظامًا قويًا يسمى:

Eloquent ORM

وفي الدرس القادم سنتعلم:

Models
Eloquent ORM
Create
Read
Update
Delete

وسنبدأ بإنشاء:

Article

ثم نربطه بجدول:

articles

وسنتعلم كيف نضيف المقالات ونقرأها ونعدلها ونحذفها باستخدام Laravel بطريقة سهلة ومنظمة.

وهنا تبدأ قاعدة البيانات بالاندماج فعليًا مع Controllers وValidation وViews التي تعلمناها في الدروس السابقة.

google-playkhamsatmostaqltradentX