تخيّل معي الوضع التالي. أنت عضو في فريق تطوير تطبيق باستخدام Laravel 4. يستخدم أعضاء الفريق git لإدارة إصدارات التطبيق وفي كل مرة يقوم عضو من أعضاء الفريق بإضافة خصائص أو إدخال تعديلات جديدة على المشروع يقوم بإيداع التغييرات في مُستودع التطبيق. إلى هنا يبدو الوضع عاديا (بل مثاليا) لكن ماذا لو قام أحد أعضاء الفريق بإدخال تعديل يتطلب إضافة جداول جديدة إلى قاعدة البيانات أو تعديل حقول وحذف أخرى، فما الحل هنا؟ هل يستطيع git مثلا أن يفي بالغرض؟ أم أنه سيتم تصدير قاعدة البيانات في كل مرة ويُطلب من كل عضو في الفريق استيرادها؟ ماذا عن البيانات التي تحتويها قاعدة البيانات؟ وهل يجب فعلا أن نتخلص من قاعدة البيانات القديمة واستبدالها بأخرى في كل مرة؟
إن كنت تستخدم إطار عمل لارافل فالحل يكمن في استخدام التهجير migrations والذي يُعتبر نظاما لإدارة الإصدارات الخاصة بقواعد البيانات، حيث أنه لن تعود هناك حاجة إلى إنشاء أي جداول أو إضافة حقول والتعديل عليها بشكل مُباشر/يدوي، وإنما يتم وصف تلك الجداول وحقولها بصيغة تجعل من التعامل مع قواعد البيانات أسهل.
قد يبدو الأمر مُعقّدا بعض الشيء، لكنه في حقيقة الأمر بسيط، وبمُجرد أن تفهم آلية عمله وتشرع في استخدامه حتى تستغرب كيف ضيعت كل الوقت السابق في إدارة قواعد البيانات يدويا. خاصية migrations مُفيدة لك حتى ولو كنت تعمل على مشروعك بشكل فردي.
بطبيعة الحال ستحتاج إلى إنشاء قاعدة بيانات للمشروع، ومن ثم التعديل على ملف app/config/database.php
بما يتوافق مع ذلك.
إنشاء ملفات migrations
لإنشاء ملف migration جديد نحتاج إلى استخدام artisan لتنفيذ الأمر migration:make
على النحو التالي مع استبدال اسم عملية التهجير بما يتوافق مع ما تقوم به (بطبيعة الحال ستحتاج إلى تنفيذ هذا الأمر بسطر الأوامر لما تكون داخل مُجلد المشروع):
php artisan migrate:make create_users_table
سيقوم laravel بإنشاء ملف جديد داخل مُجلد app/database/migrations
يحمل الاسم الذي حددته في الأمر السابق ( create_users_table
) مسبوقا بترقيم يُمثل تاريخ إنشائه حتى يتسنى لـ laravel معرفة الترتيب الذي يجب اتباعه لدى تنفيذ التهجيرات.
يُفضل استخدام أسماء للتهجيرات تدل على ما تقوم به. ففي المثال السابق أردنا إنشاء عملية تهجير جديدة لإنشاء جدول مُستخدمين، وبالتالي كان الاسم create_users_table
.
ينتج عن تنفيذ الأمر السابق ملف يحتوي:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { // } /** * Reverse the migrations. * * @return void */ public function down() { // } }
كما هو ظاهر هنا فإن الصنف CreateUsersTable
يحتوي على دالتين الأولى up
والتي تُبين ما الذي يجب القيام به لدى تنفيذ التهجير، والثانية down
والتي نُحدد فيها ما الذي يجب القيام به لدى إلغاء التهجير في حال ما إذا أردنا العودة بقاعدة البيانات إلى الحالة التي كانت عليها قبل تنفيذ التهجير.
هذا الملف لا يُحدد أي جدول نعمل عليه أو نرغب في إنشاءه. يُمكن إضافة ذلك يدويا، كما أنه يُمكن القيام بذلك عبر تحديد اسم الجدول لدى تنفيذ أمر إنشاء عملية التهجير وذلك باستخدام --create
التي تُحدد اسم الجدول الذي نرغب في إنشاءه أو --table
التي تُحدد اسم الجدول الذي نرغب في التعديل عليه. فمثلا لو حذفنا عملية التهجير السابقة ورغبنا في إعادة إنشاء أخرى مع تحديد اسم الجدول فسيكون ذلك على النحو التالي:
php artisan migrate:make create_users_table --create=users
والذي سينتج عنه ملف مثل الملف السابق، لكن هذه المرة نجد أن دالتي up
و down
تحتويان أوامر أولية:
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('user', function(Blueprint $table) { $table->increments('id'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('user'); } }
لاحظ هنا أن users هي اسم الجدول المُراد إنشاؤه والذي يكون عادة جمع اسم الـ model الذي تتعامل معه (بمعنى إن كان user هو اسم الـ model فسيكون اسم الجدول الخاص به users)
أما لو أردنا التعديل على نفس الجدول السابق وإضافة حقل جديد إليه فيكفي تنفيذ الأمر التالي:
php artisan migrate:make add_votes_to_user_table --table=users
تنفيذ عمليات التهجير
إلى حد الآن كل ما قمنا به هو إنشاء ملفات التهجير، حيث أنك لو تحققت من قاعدة البيانات لوجدتها فارغة. لتنفيذ عمليات التهجير نستعمل الأمر
php artisan migrate
وبعد ذلك ستلاحظ ظهور جدول جديد على قاعدة البيانات.
أما لو رغبت في التراجع عن آخر عملية تهجير (أو بالأحرى عن آخر جملة تهجيرات تم تنفيذها مع بعض) فإننا نستعمل الأمر:
php artisan migrate:rollback
وفي حال ما إذا رغبت في التراجع عن جميع عمليات التهجير والرجوع إلى الحالة الأولى لقاعدة البيانات فإن الأمر التالي كفيل بالقيام بذلك:
php artisan migrate:reset
ويُمكن أيضا استخدام الأمر التالي للتخلص من جميع عمليات التهجير وإعادة تنفيذها من جديد بشكل مُباشر بعد ذلك:
php artisan migrate:refresh
أنواع الحقول
رأينا في الفقرة السابقة بأن عمليات التهجير تسمح لنا بإنشاء معرف autoincrement
إضافة إلى حقلي created_at
و updated_at
بفضل دالة timestamps
. يسمح Laravel بإنشاء شتى أنواع الحقول التي قد تحتاجها في مشروعك إلى جانب إضافة خصائص للحقول وإعطائها قِيمًا أوليّة. المثال التالي يُبين بعض هذه الحقول والخصائص:
$user->string('name', 64); $user->integer('age')->nullable(); $user->boolean('active')->default(1); $user->integer('role_id')->unsigned(); $user->text('bio');
والذي يقوم بإنشاء:
- حقل
name
يكون نصيا يكون أقصر من أو يُساوي 64 محرفا. - حقل
age
يكون رقميا، كما أنه يقبل القيمة NULL - حقل
active
يكون منطقيا ويحمل قيمة أولية 1 - حقل
role_id
رقميا ويكون موجبا - حقل
bio
يكون نصيا
بإمكان الاطلاع على جميع أنواع الحقول المُمكنة من هنا
حذف الحقول
ستحتاج إلى حذف الحقول في دالة down
ويتم ذلك على النحو التالي:
Schema::table('users', function($table) { $table->dropColumn('votes'); });
بذر قواعد البيانات database seeding
المقصود ببذر قواعد البيانات هو إدخال البيانات الأولية التي نحتاجها لتجربة التطبيق. بالرغم من أن تطبيقك يسمح بإنشاء مُستخدمين جدد فإنك سترغب في استخدام مُستخدمين تجريبيين في كل مرة تُحدث تغييرات في التطبيق، وإنشاء عدد من المُستخدمين يدويا في كل مرة مضيعة للوقت. الحل يكمن في إعلام Laravel بالبيانات الأولية التي ترغب في بذر قاعدة البيانات بها بعد إنشائها ويتم ذلك عبر إنشاء ملفات بذر داخل مُجلد app/database/seeds
يحتوي الأوامر التي يجب تنفيذها.
مثال على ملف بذر يقوم بإضافة مُستخدم جديد:
class UserTableSeeder extends Seeder { public function run() { DB::table('users')->delete(); User::create(array('email' => 'foo@bar.com')); } }
لتنفيذ عملية البذر التي قمنا بإنشائها فإننا نستخدم الأمر التالي:
php artisan db:seed --class=UserTableSeeder
وإن كان لديك أكثر من ملف بذر وترغب في تنفيذها كاملة بأمر واحد فإنه يكفي القيام بذلك عبر تحديد أسماء عمليات البذر المُراد تنفيذها في صنف/ملف DatabaseSeeder
الذي ستجده داخل مُجلد app/database/seeds
على النحو التالي:
class DatabaseSeeder extends Seeder { public function run() { $this->call('UserTableSeeder'); $this->call('PostTableSeeder'); } }
وبعد ستحتاج إلى تنفيذ الأمر
php artisan db:seed
الذي سيقوم بقراءة الملف واستدعاء عمليات البذر بشكل مُتوال
بإمكانك أيضا تنفيذ عمليات البذر مُباشرة بعد تحديث عمليات التهجير على الشكل التالي:
php artisan migrate:refresh --seed
توليد بيانات تجريبية باستخدام Faker
بالرغم من أن هذه الخُطوة ليست ضرورية، إلا أنه في الكثير من الحالات ستحتاج إلى بيانات تجريبية أقرب ما تكون إلى البيانات الحقيقية للتجريب عليها. فمثلا سترغب في استخدام أسماء مُستخدمين "حقيقيين" وعناوين بريد إلكتروني، وعناوين منازل، إضافة إلى أسماء المُدن وأرقام هواتف وما إلى ذلك. بطبيعة الحال فإنه بالإمكان الاكتفاء بملفات البذر وإدخال تلك البيانات بطريقة شبه يدوية، إلا أن هناك حلا آخر يُسهّل عليك ذلك إن استعنت بمكتبة Faker للحصول على هذه البيانات.
بداية سنحتاج إلى "تنصيب" Faker وذلك على النحو التالي:
قم بالتعديل على ملف composer.json
وإضافة التالي:
"require-dev":{ "fzaninotto/faker": "1.5.*@dev" },
أو قم بإضافة "fzaninotto/faker": "1.5.*@dev"
إن كان حقل require-dev
مُتوفرا في الملف.
بعدها قم بتنفيذ الأمر php artisan update
ليقوم artisan بتحميل الملفات المطلوبة.
في غالب الأحوال ستحتاج إلى إنشاء مُستخدم غير عشوائي إلى جانب البيانات التجريبية، وعليه يُفضل إنشاؤه أولا قبل توليد البيانات العشوائية.
$user = User::create(array( 'username' => 'djug', 'first_name' => 'Youghourta', 'last_name' => 'Benali', 'email' => 'djug@someNewProject.com', 'password' => Hash::make('MySuperPassword') )); $faker = Faker\Factory::create(); for ($i = 0; $i < 25; $i++) { $user = User::create(array( 'username' => $faker->userName, 'first_name' => $faker->firstName, 'last_name' => $faker->lastName, 'email' => $faker->email, 'password' => Hash::make('Password') ));
في هذا المثال قمنا بإنشاء 25 مُستخدم يحملون أسماء بشر (وليس مُجرد حروف عشوائية) إضافة إلى عناوين بريد إلكتروني.
تسمح مكتبة Faker بتوليد شتى أنواع الحقول التي قد تحتاجها والتي يُمكن الحصول على نُسخ مُوطنة ومُترجمة منها، فمثلا يُمكن توليد أسماء عربية وعناوين فرنسية وما إلى ذلك.
للمزيد حول مكتبة Faker قم بإلقاء نظرة على مُستودع المشروع على github
وللمزيد حول جميع أنواع العمليات التي يُمكن القيام بها على الهجرات: Schema Builder
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.