يوفر تهجير قواعد البيانات Database migration في Laravel آليات لإنشاء الجداول Tablesوالتعديل عليها بغض النظر نظام إدارة قواعد البيانات المستخدم. يعني هذا أنك لن تضطر للاهتمام بالاختلافات بين نظم إدارة قواعد البيانات في صياغة أوامر SQL. يمكّن التهجير أيضا من التراجع والعودة إلى ما كانت عليه قاعدة البيانات قبل آخر التعديلات.
هذا الدرس جزء من سلسلة تعلم Laravel والتي تنتهج مبدأ "أفضل وسيلة للتعلم هي الممارسة"، حيث ستكون ممارستنا عبارة عن إنشاء تطبيق ويب للتسوق مع ميزة سلة المشتريات. يتكون فهرس السلسلة من التالي:
- مدخل إلى Laravel 5.
- تثبيت Laravel وإعداده على كلّ من Windows وUbuntu.
- أساسيات بناء تطبيق باستخدام Laravel.
- إنشاء روابط محسنة لمحركات البحث (SEO) في إطار عمل Laravel.
- نظام Blade للقوالب.
- تهجير قواعد البيانات في Laravel. (هذا الدرس)
- استخدام Eloquent ORM لإدخال البيانات في قاعدة البيانات، تحديثها أو حذفها.
- إنشاء سلة مشتريات في Laravel.
- الاستيثاق في Laravel.
- إنشاء واجهة لبرمجة التطبيقات API في Laravel.
- إنشاء مدوّنة باستخدام Laravel.
- استخدام AngularJS واجهةً أمامية Front end لتطبيق Laravel.
- الدوّال المساعدة المخصّصة في Laravel.
- استخدام مكتبة Faker في تطبيق Laravel لتوليد بيانات وهمية قصدَ الاختبار.
يمكن النظر إلى تهجير قواعد البيانات كما لو كان نظام إدارة نسخ خاص بقواعد البيانات، إذ يتيح لفريق العمل سهولة تغيير مخطّط Schema البيانات وتشاركه.
نكمل في هذا الدرس اعتمادا على ما أنشأناه في الدروس السابقة من السلسلة. يغطي الدرس المواضيع التالية:
- متطلبات التهجير.
- أمر Artisan لتهجير قواعد البيانات.
- بنية التهجير.
- إنشاء جدول بآلية التهجير.
- استخدام آلية التهجير للتراجع Rollback عن التعديلات.
- بذر قواعد البيانات Database seeding.
- بنية قاعدة البيانات الخاصة بمشروع Larashop.
- ملفات التهجير لقاعدة بيانات Larashop.
متطلبات التهجير
يجب أولا إنشاء قاعدة بيانات في نظام إدارة قواعد البيانات المستخدم (MySQL في حالتنا) وإعداد معطيات الاتصال بها في Laravel ولدى أداة سطر الأوامر Artisan.
إنشاء قاعدة بيانات
نفذ الأمر التالي في سطر أوامر MySQL أو استخدم التطبيق المفضّل لديك (PHPMyAdmin مثلا) لإنشاء قاعدة بيانات larashop:
CREATE DATABASE `larashop`;
إعداد Laravel للاتصال بقاعدة البيانات
أعددنا Laravel في الدرس الأول من هذه السلسلة للاتصال بقاعدة بيانات باسم larashop
. في ما يلي تذكير بخطوات الإعداد.
افتح الملف config/database.php
واعثر على الأسطُر التالية:
'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, ],
حدّث القيم التالية لتوافق إعدادات MySQL لديك:
'database' => env('DB_DATABASE', 'larashop'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', 'melody'),
إعداد معطيات اتصال Artisan بقاعدة البيانات
يواجه الكثير من المطورين رسالة الخطأ التالية عند العمل على تهجير قواعد البيانات باستخدام أداة Artisan:
Access denied for user 'homestead'@' localhost' (using password: YES)
ستظهر الرسالة أعلاه حتى ولو كانت معطيات الاتصال في الملف configuration/database.php
صحيحة. يعود السبب في ذلك إلى أن Artisan يستخدم المعطيات الموجودة في الملف env.
. الحل هو إذن تحرير الملف env.
الواقع في مجلد التطبيق، ستجد ما يلي:
APP_ENV=local APP_DEBUG=true APP_KEY=aqk5XHULL8TZ8t6pXE43o7MBSFchfgy2 DB_HOST=localhost DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync MAIL_DRIVER=smtp MAIL_HOST=mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null
حدث المتغيرات التالية:
DB_HOST=localhost DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret
لتصبح:
DB_HOST=localhost DB_DATABASE=larashop DB_USERNAME=root DB_PASSWORD=melody
احرص على موافقة اسم قاعدة البيانات، اسم المستخدم وكلمة مروره للمعطيات لديك. احفظ التعديلات.
تهجير قواعد البيانات بأداة Artisan
ينشئ أمر artisan ملفا على المسار database/migrations
لكل عملية تهجير. يمكن تغيير المسار الخاص بحفظ ملفات التهجير إن أردت ولكننا هنا سنكتفي بالمسار المبدئي.
ننفذ الأمر التالي لإنشاء أول ملف تهجير:
php artisan make:migration create_drinks_table
تظهر رسالة باسم ملف التهجير الجديد. اخترنا اسم create_drinks_table
للدلالة على أن التهجير ينشئ جدولا باسم drinks
في قاعدة البيانات. نتيجة الأمر هي إنشاء ملف للتهجير بنفس الاسم الذي أعطيناه مع إضافة ختم زمني قبله، مثلا:
2015_12_21_215845_create_drinks_table.php
بنية ملف التهجير
ندرس الآن محتوى ملف التهجير الذي أنشأناه للتو. افتح الملف التالي لرؤية محتواه (انتبه إلى أن اسم الملف يبدأ بختم زمني للحظة إنشائه):
database/migrations/2015_12_21_215845_create_drinks_table.php
نجد ما يلي:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateDrinksTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { // } /** * Reverse the migrations. * * @return void */ public function down() { // } }
يعرف ملف التهجير صنفا جديدا باسم
CreateDrinksTable
يمدد الصنفMigration
:
CreateDrinksTable extends Migration
داخل الصنف
CreateDrinksTable
توجد دالة باسمup
. تنفّذ تعليمات الدالةup
عند تشغيل التهجير.- توجد أيضا دالة باسم
down
في الصنفCreateDrinksTable
. تنفذ تعليمات الدالةdown
عند التراجع عن تغييراتِ تهجير.
ملف تهجير لإنشاء جدول بقاعدة البيانات
ليمكن إنشاء جدول في قاعدة البيانات فجيب تعريف حقوله في ملف التهجير. نعيد فتح ملف التهجير السابق ونعدله ليصبح محتواه التالي :
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateDrinksTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('drinks', function (Blueprint $table) { $table->increments('id'); $table->string('name',75)->unique(); $table->text('comments')->nullable(); $table->integer('rating'); $table->date('juice_date'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('drinks'); } }
- في الدالة
up
: نستدعي الدالةcreate
المعرَّفة في الصنفSchema
ونمرر لها معطيين، الأول اسم الجدول الذي نريد إنشاءهdrinks
، والمعطى الثاني دالة غير محدّدة الاسم تعرّف حقول الجدول. نستخدم كائنا من صنفBlueprint
لتعريف الجدول. - نعرف أول حقل من الجدول وهو الحقل
id
. تعرف الدالةincrements
التابعة للصنفBlueprint
عددا طبيعيا (عدد صحيح إشارته موجبة) يزداد تلقائيّا مع كل إدخال للبيانات في الجدول. - الحقل الثاني هو حقل الاسم
name
، الذي نعرفه بالدالةstring
. تنشئ الدالةstring
حقلا من سلسلة محارف مع تحديد طول السلسلة (75 في المثال). نعلّم الحقلname
بالدالةunique
\لجعله وحيدا وهو ما يعني أنه لا يمكن لتسجيلتين في الجدول أن تحويا نفس القيمة بالنسبة لهذا الحقل. - الحقل الثالث
comments
نصي، وتستخدم الدالةtext
لتعريفه. نتيح إمكانية ألا يحوي الحقل بيانات باستخدام الدالةnullable
. - الحقل الرابع
rating
للتقيمات. نستخدم الدالةinteger
للإشارة إلى أنه عدد صحيح. - ثم نضيف حقلا لتخزين تاريخ المشروب
juice_date
ونستخدم الدالةdate
لهذا الغرض. - تُستخدم الدالة
timestamps
لإضافة حقلين هماcreated_at
وupdated_at
في الجدول تلقائيا. الحقلان عبارة عن ختم زمني ل، على التوالي، تاريخ إضافة التسجيلة إلى قاعدة البيانات وتاريخ آخر تحديث عليها. - في الدالة
down
نحذف الجدولdrinks
من قاعدة البيانات في حالة وجوده.
ننفذ بعد حفظ ملف التهجير الأمر التالي:
php artisan migrate
ستظهر مخرجات في سطر الأوامر على النحو التالي:
Migration table created successfully. Migrated: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_100000_create_password_resets_table Migrated: 2015_12_21_215845_create_drinks_table
إن نظرت في جداول قاعدة البيانات الآن فستجد التالي:
ستلاحظ وجود أربعة جداول من بينها جدول drinks
. الجداول الأخرى أنشأها Laravel لأن ملفات تهجيرها تأتي مبدئيا مع Laravel.
التراجع عن التعديلات
يوفر التهجير إمكانية التراجع عن تعديلاته والعودة إلى حالة قاعدة البيانات قبل تنفيذه. أنشأنا في الفقرة السابقة جداول في قاعدة البيانات، ننفذ الأمر التالي للتراجع عن ذلك:
php artisan migrate:rollback
تظهر الرسائل التالية:
Rolled back: 2015_12_21_215845_create_drinks_table Rolled back: 2014_10_12_100000_create_password_resets_table Rolled back: 2014_10_12_000000_create_users_table
إن أعدت التحقق في MySQL سترى أن الجدول drinks
لم يعد موجودا.
نعيد إنشاء الجدول بتنفيذ التهجير مرة أخرى:
php artisan migrate
تمكن ملاحظة أن تنفيذ التهجير يكون بالتسلسل الزمني التصاعدي لتاريخ إنشاء ملفات التهجير (من الأقدم إلى الأحدث)، في ما يكون التراجع بتنفيذ ملفات التهجير حسب التسلسل الزمني التنازلي (من الأحدث إلى الأقدم).
إدارة جداول البيانات في Laravel باستخدام التهجير
سنرى في هذه الفقرة كيفية استخدام التهجير للقيام بأشغال شائعة على جداول قواعد البيانات.
إدراج بيانات
سنرى الآن كيفية استخدام التهجير لإدراج بيانات في جدول أثناء إنشائه. ننشئ جدولا بالموظفين employees
وندرج فيه 33 تسجيلة بالاعتماد على مكتبة Faker (سنخصص درسا لتفصيل استخدام Faker).
نفذ الأمر التالي لإنشاء ملف تهجير لجدول employees
:
php artisan make:migration employees
نفتح الملف المنشأ للتو ونضيف الشفرة التالية:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class Employees extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('employees', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('contact_number'); $table->timestamps(); }); $faker = Faker\Factory::create(); $limit = 33; for ($i = 0; $i < $limit; $i++) { DB::table('employees')->insert([ //, 'name' => $faker->name, 'email' => $faker->unique()->email, 'contact_number' => $faker->phoneNumber, ]); } } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('employees'); } }
ننشئ كائنا من صنف Faker بالتعليمة
$faker = Faker\Factory::create();
نحدد عدد التسجيلات التي نود إدراجها:
limit$
.- نستخدم حلقة
for
التكرارية لإضافة التسجيلات إلى الجدول. تولد التعليمةfaker->name$
اسما وهميّا،faker->unique()->email$
اسم بريد وحيد وfaker->phoneNumber$
رقم هاتف وهميا.
الأمر التالي ينفذ التهجير:
php artisan migrate
تظهر الرسالة التالية دلالة على تهجير الجدول employees
:
Migrated: 2015_12_21_225233_employees
إن بحثت الآن عن محتوى الجدول employees
، مثلا بتنفيذ الاستعلام التالي في سطر أوامر MySQL:
SELECT * FROM employees;
ستحصُل على أسماء الموظفين، عناوينهم البريدية وأرقام هواتفهم.
نتراجع عن إنشاء الجدول employees
بتنفيذ الأمر:
php artisan migrate:rollback
تظهر رسالة دلالة على التراجع عن إنشاء الجدول. نفتح ملف التهجير للتعديل عليه ثم نضع الشفرة الخاصة بإدراج بيانات وهمية بين علامتي تعليق، هكذا:
/* $faker = Faker\Factory::create(); $limit = 33; for ($i = 0; $i < $limit; $i++) { DB::table('employees')->insert([ //, 'name' => $faker->name, 'email' => $faker->unique()->email, 'contact_number' => $faker->phoneNumber, ]); } */
احفظ ملف التهجير ثم نفذ الأمر:
php artisan migrate
سيُنشأ جدول employees
من جديد ولكن هذه المرة دون إدراج تسجيلات في الجدول.
إضافة عمود إلى جدول أو حذفه منه
نفرض أننا نود إضافة عمود جديد gender
لتخزين جنس الموظّف، مباشرة بعد العمود contact_number
. ننفذ الأمر التالي لإنشاء ملف تهجير باسم add_gender_to_employees
مع تحديد الجدول الذي نريد العمل عليه وهو employees
:
php artisan make:migration add_gender_to_employees --table=employees
تشير التعليمة table=employees--
إلى أننا نريد العمل على الجدول employees
الموجود في قاعدة البيانات.
افتح ملف التهجير المنشأ بعد الأمر السابق، وعدله ليصبح على النحو التالي:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddGenderToEmployees extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('employees', function (Blueprint $table) { $table->string('gender')->after('contact_number'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('employees', function (Blueprint $table) { $table->dropColumn('gender'); }); } }
- في الدالة
up
أضفنا حقلا جديدا من نوعstring
(سلسلة محارف) وحددنا مكانه بأنه بعد العمودcontact_number
. - في الدالة
down
نحذف الحقلgender
.
الآن عند تنفيذ أمر التهجير php artisan migrate
ستلاحظ إضافة عمود جديد باسم gender
بعد عمود contact_number
.
تغيير نوع عمود
يحتاج تغيير نوع العمود لتثبيت حزمة Doctrine Database Abstract Layer, DBAL. تُستخدم هذه الحزمة لتهجيرات التعديل على الجداول Alter table.
سنستخدم أداة إدارة الاعتماديات Composer لتثبيت الحزمة. افتح ملف composer.json
الذي يوجد في مجلد التطبيق. ابحث عن مقطع require
:
"require": { "php": ">=5.5.9", "laravel/framework": "5.2.*" },
توجد في هذا المقطع حزم المكتبات التي يحتاجها تطبيقنا. حتى الآن توجد حزمتان فقط هما php
وlaravel
. يشير الجزء الأول (قبل النقطتين) إلى اسم الحزمة، في ما يشير الثاني لإصدارها. نضيف حزمة dbal` إلى هذه الاعتماديات، وذلك على النجو التالي:
"require": { "php": ">=5.5.9", "laravel/framework": "5.2.*", "doctrine/dbal": "v2.4.2" },
لاحظ الفاصلة اللاتينية التي أضفناها بعد حزمة Laravel.
نفذ الأمر التالي لتحديث المشروع:
composer update
عند إنشاء العمود gender
لم نحدد طول الحقل، أي أنه سيأخذ الطول المبدئي للحقول من نوع string
وهو255 محرفا. ننشئ ملف تهجير جديدا لتعديل طول الحقل ليصبح 5 كحد أقصى.
نعدل الملف على النحو التالي:
php artisan make:migration modify_gender_in_employees --table=employees
قبول فراغ الحقول في الجدول
يفترض Laravel عند إنشاء الحقول أنها لا تقبل فراغ القيمة، أي أنه يجب ذكر قيمة للحقل عند إدراج تسجيلات في الجدول. يمكننا تغيير هذا الإعداد المبدئي وجعل قيمة حقل ما اختيارية. سنأخذ الحقل gender
للتمثيل به.
ننشئ ملفا للتهجير:
php artisan make:migration make_gender_null_in_employees --table=employees
ثم نعدله على النحو التالي:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class MakeGenderNullInEmployees extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('employees', function (Blueprint $table) { $table->string('gender', 5)->nullable()->change(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('employees', function (Blueprint $table) { $table->string('gender', 5)->change(); }); } }
- تجعل الدالة
nullable
الحقلgender
يقبل قيما فارغة.
php artisan migrate
إضافة مفتاح خارجي Foreign key
نصنف موظفينا حسب القسم الذي يعملون فيه. ننشئ جدولا للأقسام depts
ثم نضيف مفتاحا خاريجا في جدول الموظفين employees
.
الأمر أدناه ينشئ ملف تهجير لجدول الأقسام:
php artisan make:migration depts
عدل ملف التهجير:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class Depts extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('depts', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('depts'); } }
ثم ننفذ أمر التهجير لإنشاء الجدول:
php artisan migrate
يُشترط لتصح علاقة عبر مفتاح خارجي بين جدولين أن يكون المفتاح الخارجي والمفتاح الرئيس Primary key متطابقين في النوع. استخدمنا في تعريف المفتاح الرئيس id
ضمن الجدول depts
دالة increments
التي تعطي النوع عددا طبيعيا من عشرة أرقام ;(unsigned integer INT(10
وهو ما يعني أننا سنعطي نفس النوع للمفتاح الخارجي الذي سننشئه في الجدول employees
. الفرق أن المفتاح الخارجي لا يزداد تلقائيا لذا سنستخدم الدالة unsignedInteger
التي لها نفس مفعول increments
من حيث نوع الحقل وطوله، مع فرق أنها لا تضيف الازدياد التلقائي.
ملحوظة: حتى تمكن إضافة مفتاح خارجي في الجدول employees
يجب أن يكون الجدول فارغا (بدون تسجيلات). لهذا السبب علقنا في فقرة ماضية الشفرة الخاصة بـFaker.
نفذ الأمر التالي لإنشاء ملف تهجير لإضافة حقل المفتاح الخارجي dept_id
إلى الجدول employees
:
php artisan make:migration add_dept_id_in_employees --table=employees
ثم نعدل ملف التهجير:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddDeptIdInEmployees extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('employees', function (Blueprint $table) { $table-> unsignedInteger ('dept_id')->after('gender'); $table->foreign('dept_id') ->references('id')->on('depts') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('employees', function (Blueprint $table) { $table->dropColumn('dept_id'); }); } }
ثم ننفذ التهجير:
php artisan migrate
بذر قواعد البيانات
يشير مصطلح البذر Seeding إلى عملية إضافة بيانات وهمية لأغراض الاختبار في قواعد البيانات. نطبق هذا الإجراء على جدول drinks
الذي أنشأناه في أول الدرس.
نفذ الأمر التالي لإنشاء ملف للبذر:
php artisan make:seeder DrinksTableSeeder
ينشئ الأمر ملفا باسم DrinksTableSeeder.php
على المسار database/seeds
. افتح الملف:
<?php use Illuminate\Database\Seeder; class DrinksTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // } }
يمدد الصنف DrinksTableSeeder الصنف Seeder ويعرّف الدالة run التي تُنفّذ عند تشغيل أمر البذر في Artisan.
عدل الملف ليصبح محتواه التالي:
<?php
use Illuminate\Database\Seeder;
class DrinksTableSeeder extends Seeder {
/**
* Run the database seeds.
*
* @return void
*/
public function run() {
DB::table('drinks')->insert([
'name' => 'Orange Juice',
'comments' => 'Rich in C vitamin',
'rating' => 9,
'juice_date' => '2015-12-20',
]);
}
أضفنا في الدالة run أمر إدراج في جدول البيانات drinks ومررنا مصفوفة توافق عناصرها حقول الجدول مع تحديد قيم عناصر المصفوفة. ننفذ الأمر أمر البذر لإضافة التسجيلة أعلاه إلى الجدول:
php artisan db:seed --class=DrinksTableSeeder
نمرر لأمر البذر php artisan db::seed اسم الملف المراد تنفيذه.
الآن عند التحقق نجد في جدول قاعدة البيانات التسجيلة التالية:
قاعدة البيانات الخاصة بمشروع Larashop
تعرفنا في الفقرات الماضية على أساسيات التهجير في Laravel. سنجعل هذه المعرفة موضع التطبيق لإنشاء قاعدة بيانات لمشروع Larashop.
ستشنرك جميع الجداول في الحقول التالية التي أنشأناها لأغراض الفحص والتدقيق.
التسلسل | الحقل | نوع البيانات | الوصف |
---|---|---|---|
1 | created_at | Timestamp | ختم زمني لتاريخ إدراج التسجيلة |
2 | updated_at | Timestamp | ختم زمني لتاريخ تحديث التسجيلة |
3 | created_at_ip | (Varchar(45 | عنوان IP المستخدم لإدراج التسجيلة |
4 | updated_at_ip | (Varchar(45 | عنوان IP المستخدم لتحديث التسجيلة |
جدول منشورات المدونة
التسلسل | الحقل | نوع البيانات | الوصف |
---|---|---|---|
1 | id | INT | مفتاح رئيس (AUTOINCREMENT) عدد طبيعي يزداد تلقائيا |
2 | url | (Varchar(255 | رابط الصفحة |
3 | title | (Varchar(140 | عنوان الصفحة |
4 | description | (Varchar(170 | وصف يظهر في محركات البحث |
5 | content | Text | محتوى الصفحة أو المنشور |
6 | conblogtent | (Tinyint(1 | يحدد ما إذا كان المنشور صفحة |
جدول التصنيفات
التسلسل | الحقل | نوع البيانات | الوصف |
---|---|---|---|
1 | id | INT | مفتاح رئيس (AUTOINCREMENT) عدد طبيعي يزداد تلقائيا |
2 | name | (Varchar(255 | اسم التصنيف |
جدول العلامات التجارية
التسلسل | الحقل | نوع البيانات | الوصف |
---|---|---|---|
1 | id | INT | مفتاح رئيس (AUTOINCREMENT) عدد طبيعي يزداد تلقائيا |
2 | name | (Varchar(255 | اسم العلامة التجارية |
جدول المنتجات
لكل منتج تصنيف وعلامة تجارية وحيدين.
التسلسل | الحقل | نوع البيانات | الوصف |
---|---|---|---|
1 | id | INT | مفتاح رئيس (AUTOINCREMENT) عدد طبيعي يزداد تلقائيا |
2 | name | (Varchar(255 | اسم المنتج |
3 | title | (Varchar(140 | عنوان المنتج |
4 | description | (Varchar(500 | عنوان المنتج |
5 | price | int | ثمن المنتج |
6 | category_id | int | معرف تصنيف المنتج |
7 | brand_id | int | معرف العلامة التجارية للمنتج |
ملفات التهجير لجداول قاعدة بيانات المشروع
سننشئ في هذه الفقرة ملفات تهجير لجداول البيانات المذكورة أعلاه؛ سنضيف أيضا بعض البيانات الوهمية إلى الجداول باستخدام آلية البذر التي تعرفنا عليها سابقا.
توليد ملفات التهجير
افتح سطر الأوامر ونفذ الأوامر التالية لتوليد ملفات الجداول:
جدول منشورات المدونة:
php artisan make:migration create_posts_table
جدول تصنيفات المنتجات
php artisan make:migration create_categories_table
جدول العلامات التجارية للمنتجات
php artisan make:migration create_brands_table
جدول المنتجات
php artisan make:migration create_products_table
تحرير ملفات التهجير
ننتقل لتحرير كل ملف من ملفات التهجير.
جدول منشورات المدونة
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreatePostsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('url', 255)->unique(); $table->string('title', 140); $table->string('description', 170); $table->text('content'); $table->boolean('blog'); $table->timestamps(); $table->string('created_at_ip'); $table->string('updated_at_ip'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('posts'); } }
جدول التصنيفات
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCategoriesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('categories', function (Blueprint $table) { $table->increments('id'); $table->string('name', 255)->unique(); $table->timestamps(); $table->string('created_at_ip'); $table->string('updated_at_ip'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('categories'); } }
جدول العلامات التجارية
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateBrandsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('brands', function (Blueprint $table) { $table->increments('id'); $table->string('name', 255)->unique(); $table->timestamps(); $table->string('created_at_ip'); $table->string('updated_at_ip'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('brands'); } }
جدول المنتجات
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateProductsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('products', function (Blueprint $table) { $table->increments('id'); $table->string('name', 255)->unique(); $table->string('title', 140); $table->string('description', 500); $table->integer('price'); $table->unsignedInteger('category_id'); $table->unsignedInteger('brand_id'); $table->timestamps(); $table->string('created_at_ip'); $table->string('updated_at_ip'); // مفتاح خارجي على جدول التصنيفات $table->foreign('category_id') ->references('id')->on('categories') ->onDelete('cascade'); // مفتاح خارجي على جدول العلامات التجارية $table->foreign('brand_id') ->references('id')->on('brands') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('products'); } }
بذر قاعدة بيانات المشروع
ندرج بيانات وهمية في جداول قاعدة البيانات قصدَ الاختبار.
أنشئ ملفات البذر بتنفيذ الأوامر أدناه على التوالي:
php artisan make:seeder CategoriesTableSeeder php artisan make:seeder BrandsTableSeeder php artisan make:seeder ProductsTableSeeder
يحوي جدول المنتجات مفتاحين خارجيين لجدولي التصنيف والعلامة التجارية. لذا يجب البدء بهما (لا يصح إدراج مفتاح خارجي لتسجيلة غير موجودة في الجدول الذي مثل المفتاح الخارجي مرجعا إليه).
بذر جدول التصنيفات
<?php use Illuminate\Database\Seeder; class CategoriesTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('categories')->insert(['name' => 'MENS']); DB::table('categories')->insert(['name' => 'WOMENS']); DB::table('categories')->insert(['name' => 'KIDS']); DB::table('categories')->insert(['name' => 'FASHION']); DB::table('categories')->insert(['name' => 'CLOTHING']); } }
- بذر جدول العلامات التجارية
<?php use Illuminate\Database\Seeder; class BrandsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('brands')->insert(['name' => 'ACNE']); DB::table('brands')->insert(['name' => 'RONHILL']); DB::table('brands')->insert(['name' => 'ALBIRO']); DB::table('brands')->insert(['name' => 'ODDMOLLY']); } }
- بذر جدول المنتجات
<?php use Illuminate\Database\Seeder; class ProductsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('products')->insert(['name' => 'Mini skirt black edition', 'title' => 'Mini skirt black edition','description' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna','price' => 35,'category_id' => 1,'brand_id' => 1,]); DB::table('products')->insert(['name' => 'T-shirt blue edition', 'title' => 'T-shirt blue edition','description' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna','price' => 64,'category_id' => 2,'brand_id' => 3,]); DB::table('products')->insert(['name' => 'Sleeveless Colorblock Scuba', 'title' => 'Sleeveless Colorblock Scuba','description' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna','price' => 13,'category_id' => 3,'brand_id' => 2,]); } }
ثم ننفذ أوامر البذر لكل جدول.
خاتمة
تعرفنا في هذا الدرس على تهجير قواعد البيانات وبذرها في Laravel. كما أننا حددنا هيكلة قاعدة بيانات المشروع الذي نعمل عليه. في الدروس القادمة سنتعرف على إطار عمل Eloquent الذي سنعتمد عليه للتخاطب مع قاعدة البيانات وعرض محتوياتها عند الاقتضاء.
ترجمة -وبتصرّف- لمقال Laravel 5 Migrations لصاحبه Rodrick Kazembe.
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.