تعداد بازدید: 1891

Database Seeding

seeding یک امکان برای تولید داده (dummy content) به صورت انبوه برای جداول پایگاه داده می باشد.

دقت داشته باشید که seeding مربوط به پایگاه داده می شود و دایرکتوری های آن در مسیر database/seeds می باشد.

روال کار به این گونه است که ما یک قالب مولد به ازای هر مدل داریم (Factory) که با استفاده از آن در ModelTableSeeder (Seeder) می توانیم به تعداد دلخواه داده وارد کنیم. در نهایت DatabaseSeeder را داریم که این ModelTableSeeder ها را یک به یک run می کند و داده ها وارد می شوند.

مفاهیمی که در رابطه با Database Seeder مورد بررسی قرار می دهیم :

  • DatabaseSeeder
  • ModelTableSeeder
  • ModelFactory

ModelFactory

به ازای هر model یک factory می سازیم و در اون قالب جدول اون مدل رو مقدار دهی می کنیم. برای این کار از کتابخانه faker استفاده می کنیم که می توان با آن مقادیر مختلفی از انواع مختلف (اسم ، فامیل ، تاریخ ، …) ساخت.

برای انتخاب نام برای factory از قالب ModelFactory استفاده می کنیم. یعنی اگر نام مدل Category باشد نام انتخابی برابر CategoryFactory می شود.

گفتیم به ازای هر model یک factory پس باید نام مدل آن را در زمان ساخت تعیین کنیم (با استفاده از پارامتر --model)

php artisan make:factory CategoryFactory --model=Category

نکته : در زمان ساخت مدل نیز می توان با پارامتر -f برای مدل جاری Factory نیز ساخت. پارامتر -m برای migration می باشد.

php artisan make:model -mf

وقتی با استفاده از فرمان بالا factory می سازید فایل در مسیر database/factories ساخته می شود. در این فایل شما باید قالب ایجاد یک شئ از مدل یا همان ساخت یک ردیف از جدول مربوط به مدل جاری را وارد کنید. کتابخانه faker که با متغیر $faker در کد های زیر نمایش داده می شود می تواند به ازای هر بار درخواست یک رشته خاص و تصادفی تولید کند. به همین ترتیب می توان گفت که داده های وارد شده متفاوت هستند.

<?php

use Faker\Generator as Faker;

$factory->define(App\category::class, function (Faker $faker) {
    return [
        'name' => ucfirst($faker->unique()->word)
    ];
});

نکته : در factories نیازی به پر کردن کلید های خارجی نیست . آن ها با استفاده از روابط در seeder ها پر می شوند.

همان طور که در کد بالا مشاهده می کنید فیلد هایی که قابل پر کردن باشند به ازای مدل Category می توان ساخت.

به صورت کلی می توان گفت که factory یک کارخانه ایجاد شئ از روی مدل است .و هر جا یک مدل سریع نیاز داشتیم می توانیم از روی factory آن را بسازیم . مثلا در زمان testing می توان شئ ساخت.

ModelTableSeeder

ModelTableSeeder یک مکان برای ساخت و ذخیره اشیا به صورت انبوه بر اساس مدل خاص و با استفاده از ModelFactory که در مرحله قبل ساختیم .

برای انتخاب نام بهتر است که از قالب ModelTableSeeder استفاده کنیم. یعنی اگر مدل برابر با Product بود می شود : ProductTableSeeder.

seeder یک مکان برای اجرای کد است. یعنی با استفاده از فرمان db:seed تمامی seeder هایی که در DatabaseSeeder فراخوانی شده بودند به ترتیب اجرا می شوند. پس ما می توانیم هم به صورت دستی داده وارد کنیم (یعنی با استفاده از مدل مربوطه و متد create شئ ساخته و ذخیره کنیم) و هم از Factory ها استفاده کنیم.

php artisan make:seeder CategoryTableSeeder

پس از اجرای دستور بالا فایل CategoryTableSeeder در مسیر database/seeds ساخته می شود. ما با استفاده از تابع کمکی factory چند محصول به آن اضافه می کنیم.

<?php
use Illuminate\Database\Seeder;

class categoryTableSeeder extends Seeder
{
    public function run()
    {
        factory('App\category',3)->create()->each(function($category){
            echo $category->name . " Was Created \n";
        });
    }
}

کد بالا تعداد 3 دسته بندی رو با استفاده از قالب CategoryFactory می سازه. در مثال ما برای ساده سازی از روابط استفاده نشده. برای ساخت بر اساس روابط می توانید دقیقا همان گونه که در مدل ها عمل می کردید از روابط اشیا استفاده کنید.

تابع factory بر اساس مدل داده شده تعداد شئ می سازد و با استفاده از متد each به ازای هر کدام می توانید کار خاصی انجام دهید.

در مثال زیر فرض می کنیم UserFactory , ProductFactory , CategoryFactory را داریم. همچنین با استفاده از CategoryTableSeeder یه تعداد دسته بندی در پایگاه داده ذخیره شده باشه (CategoryTableSeeder در ابتدا اجرا بشه بعد UserTableSeeder ، چون قراره از دسته بندی های ساخته شده بر اساس id در UserTableSeeder استفاده کنیم).

در UserTableSeeder می خواهیم دو کاربر بسازیم به ازای هر کاربر 5 محصول و به هر محصول یه سری دسته بندی رو attach کنیم. کافیه به روش زیر عمل کنیم:

<?php

use Illuminate\Database\Seeder;

class userTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory('App\User',2)->create()->each(function($user){
            for($i=0;$i<5;$i++){
                $product = $user->products()->create(factory('App\products')->make()->toArray());
                $product->categories()->attach([rand(1,3)]);
            }
        });
    }
}

factory() متد های مختلفی داره که به صورت chain استفاده می شه:

  • create : اشیا رو از روی مدل و تعداد درخواستی (پارامتر هاش) میسازه و در پایگاه داده ذخیره می کنه.
  • make : اشیا رو بر اساس مدل داده شده و تعداد می سازه و به صورت دسته ای از collection ها بر می گردونه.
  • each : این تابع به make و create متصل (chain) میشه و یه پارامتر می گیره که همون شئ ساخته شده از مدل می باشد. یعنی به ازای هر بار ساخت یه callback رو میتونه اجرا کنه.

DataBaseSeeder

ModelFactory ها ساخته شدند. ModelTableSeeder ها هم ساخته شدن و در اون ها از ModelFactory استفاده شد و آماده run شدند می باشند. حالا باید جایی باشه که ترتیب اجرای این seeder ها رو در خودش معین کنه .

DatabaseSeeder در مسیر database/seeds وجود دارد که ما باید با قالب زیر بریم و ModelTableSeeder هایی که ساختیم رو در متد run اون فراخوانی کنیم. تا پس از اجرا دستور db:seed تمامی اون ها اجرا بشن و داده ها وارد بشن.

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // $this->call(UsersTableSeeder::class);
    }
}

مثلا ما ابتدا CategoryTableSeeder و بعد از اون UserTableSeeder رو در اون اجرا می کنیم.

<?php
public function run()
{
    $this->call(categoryTableSeeder::class);
    $this->call(userTableSeeder::class);
}

شبیه سازی روال در دنیای واقعی  :

فرض کنید یک کارخانه (Factory) داریم که طراحی قالب محصول (ساختار مدل تبدیل به قالب factory) می کند. و یک خط تولید (ModelTableSeeder) که این محصولات را از روی قالب ارسالی می سازد  و یک اتاق کنترل (DatabaseSeeder) که این خط تولید ها را استارت می زند.

 

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

۰ دیدگاه برای Database Seeding

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *