Laravel - Database Model Seeder

 

Database Model Seeder

Menambahkan user_id ke table blog_posts

Pertama kita akan Menambahkan migration

php artisan make:migration add_user_to_blog_posts_table

Buka file database/migrations/xxxx_xx_xx_xxxxxx_add_user_to_blog_posts_table.php, kemudian tambahkan code dibawah ini

<?php

 

use Illuminate\Database\Migrations\Migration;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\Schema;

 

class AddUserToBlogPostsTable extends Migration

{

    /**

     * Run the migrations.

     *

     * @return void

     */

    public function up()

    {

        Schema::table('blog_posts'function (Blueprint $table) {

            $table->bigInteger('user_id')->unsigned()->nullable();

 

            $table->foreign('user_id')->references('id')->on('users');

        });

    }

 

    /**

     * Reverse the migrations.

     *

     * @return void

     */

    public function down()

    {

        Schema::table('blog_posts'function (Blueprint $table) {

            $table->dropForeign(['user_id']);

            $table->dropColumn('user_id');

        });

    }

}

 

 

Jalankan migration untuk menambahkan column pada table blog_posts

php artisan migrate



Setelah migration, maka column user_id akan menjadi NULL, silahkan isi dengan nilai ada di table users. Kasus di atas secara best practice tidak disarankan, karena kita membiarkan foreign key menjadi NULLABLE

Refreshing Database

Perhatian : Jangan lakukan metode ini di production mode.

Sekarang kita akan me-refresh database, artinya kita akan menjalankan function down() kemudian menjalankan function up() dari semua file migration. Efek samping nya, semua data di database akan hilang. Sebelum menjalankan refresh database, kita perlu ubah dulu table migration database/migrations/xxxx_xx_xx_xxxxxx_add_user_to_blog_posts_table.php untuk memastikan user_id tidak NULLABLE.

Untuk me-refresh database, jalankan command dibawah ini

php artisan migrate:refresh



 

Silahkan jalankan server nya dan buka di browser atau cek di database, maka datanya sudah tidak ada.Untuk mengisi kembali data-data tersebut kita akan menggunakan fitur seeder dari laravel. Untuk menjalankan fitur tersebut cukup dengan menjalankan command dibawah ini.

php artisan db:seed

ersebut belum memberikan efek apapun ke database, karena kita belum mengupdate file database/seeders/DatabaseSeeder.php.

Basic Database Seeder

Buka file database/seeders/DatabaseSeeder.php, ubah menjadi seperti ini.

<?php

 

namespace Database\Seeders;

 

use Illuminate\Database\Seeder;

use Illuminate\Support\Facades\DB;

use Illuminate\Support\Str;

 

class DatabaseSeeder extends Seeder

{

    /**

     * Seed the application's database.

     *

     * @return void

     */

    public function run()

    {

        DB::table('users')->insert([

            'name' => "User 1",

            'email' => "user1@mail.com",

            'email_verified_at' => now(),

            'password' => bcrypt('password'),

            'remember_token' => Str::random(10)

        ]);

        // \App\Models\User::factory(10)->create();

    }

}

 

Lalu jalankan perintah ini pada terminal

Php artisan db:seed

Sekarang kita lihat di table users, row dengan email user1@mail.com sudah terinput


Jika kita menjalankan seeder kembali, maka hasilnya akan mendapatkan error seperti ini.







Error tersebut terjadi karena ada duplicate email. Untuk menjalankan kembali seeder kita harus memastikan data di table terkait harus benar-benar empty. Jadi kita harus menjalankan dulu refresh database command, kemudian jalan seeder command. Laravel sudah menyediakan fungsi untuk melakukan hal ini.

php artisan migrate:refresh --seed


Menggunakan Model Factory Untuk Database Seeder

Menggunakan model factory untuk melakukan seeding table users. Buka file database/seeders/DatabaseSeeder.php, ubah menjadi seperti ini

public function run()

{

    DB::table('users')->insert([

        'name' => "User 1",

        'email' => "user1@mail.com",

        'email_verified_at' => now(),

        'password' => bcrypt('password'),

        'remember_token' => Str::random(10)

    ]);

 

    // Model Factory

    \App\Models\User::factory()->count(10)->create();

}

Lihat di table users, akan ada 11 rows yang sudah terinput


Data pada rows 2-11, dibuat berdasarkan pada file UserFactory (database/factories/UserFactory.php). secara default akan memanggil function definition() pada file database/factories/UserFactory.php.

Kita bisa membuat custom function, dalam hal ini disebut dengan istilah state. Untuk membuat UserFactory state, kita bisa menambahkan fungsi baru.  Dalam kasus ini, kita akan memindahkan code user1 @mail.com seeder ke UserFactory file. Buka file database/factories/UserFactory.php dan tambahkan code dibawah ini

<?php

 

namespace Database\Factories;

 

use App\Models\User;

use Illuminate\Database\Eloquent\Factories\Factory;

use Illuminate\Support\Str;

 

class UserFactory extends Factory

{

    /**

     * The name of the factory's corresponding model.

     *

     * @var string

     */

    protected $model = User::class;

 

    /**

     * Define the model's default state.

     *

     * @return array

     */

    public function definition()

    {

        return [

            'name' => $this->faker->name,

            'email' => $this->faker->unique()->safeEmail,

            'email_verified_at' => now(),

            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'// password

            'remember_token' => Str::random(10),

        ];

    }

 

    public function userSatu()

    {

        return $this->state([

            'name' => "User 1",

            'email' => "user1@mail.com",

            'email_verified_at' => now(),

            'password' => bcrypt('password'),

            'remember_token' => Str::random(10)

        ]);

    }

}

 

 

Buka file database/seeders/DatabaseSeeder.php, dah ubah menjadi seperti ini.

<?php

 

namespace Database\Seeders;

 

use Illuminate\Database\Seeder;

use Illuminate\Support\Facades\DB;

use Illuminate\Support\Str;

 

class DatabaseSeeder extends Seeder

{

    /**

     * Seed the application's database.

     *

     * @return void

     */

    public function run()

    {

        // DB::table('users')->insert([

        //     'name' => "User 1",

        //     'email' => "user1@mail.com",

        //     'email_verified_at' => now(),

        //     'password' => bcrypt('password'),

        //     'remember_token' => Str::random(10)

        // ]);

 

        // Model Factory UserSatu

        \App\Models\User::factory()->userSatu()->create();

 

        // Model Factory

        \App\Models\User::factory()->count(10)->create();

    }

}

Jalankan command refresh-seeder

php artisan migrate:refresh –seed

SIlahkan coba login dengan email pada rows 1 - 11 dengan passwordnya password

 

Model Factory Untuk BlogPost

Buat BlogPost model factory dengan menjalankan command di bawah ini. Code di bawah ini akan membuat file database/factories/BlogPostFactory.php.

php artisan make:factory BlogPostFactory



Buka file database/factories/BlogPostFactory.php dan tambahkan code di bawah ini

<?php

 

namespace Database\Factories;

 

use App\Models\BlogPost;

use Illuminate\Database\Eloquent\Factories\Factory;

 

class BlogPostFactory extends Factory

{

    /**

     * The name of the factory's corresponding model.

     *

     * @var string

     */

    protected $model = BlogPost::class;

 

    /**

     * Define the model's default state.

     *

     * @return array

     */

    public function definition()

    {

        return [

            "title" => $this->faker->sentence(15),

            "content" => $this->faker->paragraphs(5true)

        ];

    }

}

 

 

Buka file database/seeders/DatabaseSeeder.php, dah ubah menjadi seperti ini.

<?php

 

namespace Database\Seeders;

 

use Illuminate\Database\Seeder;

use Illuminate\Support\Facades\DB;

use Illuminate\Support\Str;

 

class DatabaseSeeder extends Seeder

{

    /**

     * Seed the application's database.

     *

     * @return void

     */

    public function run()

    {

        // DB::table('users')->insert([

        //     'name' => "User 1",

        //     'email' => "user1@mail.com",

        //     'email_verified_at' => now(),

        //     'password' => bcrypt('password'),

        //     'remember_token' => Str::random(10)

        // ]);

 

        // Model Factory UserSatu

        \App\Models\User::factory()->userSatu()->create();

 

        // Model Factory User

        \App\Models\User::factory()->count(10)->create();

 

        // Model Factory BlogPost

        \App\Models\BlogPost::factory()->count(5)->create();

 

    }

}

 

 

Ketika menjalankan command refresh-seeder, maka akan muncul error seperti dibawah ini.

php artisan migrate:refresh --seed



Error ini terjadi karena kita tidak mengisi column user_id. Column user_id ini harus di isi dengan value yang real dan ada pada table users.id. Untuk menangani masalah ini, kita perlu mengubah file DatabaseSeeder. Buka file database/seeders/DatabaseSeeder.php dan tambahkan code di bawah ini

<?php

 

namespace Database\Seeders;

 

use Illuminate\Database\Seeder;

use Illuminate\Support\Facades\DB;

use Illuminate\Support\Str;

 

class DatabaseSeeder extends Seeder

{

    /**

     * Seed the application's database.

     *

     * @return void

     */

    public function run()

    {

        // DB::table('users')->insert([

        //     'name' => "User 1",

        //     'email' => "user1@mail.com",

        //     'email_verified_at' => now(),

        //     'password' => bcrypt('password'),

        //     'remember_token' => Str::random(10)

        // ]);

 

        // Model Factory UserSatu

        $userSatu = \App\Models\User::factory()->userSatu()->create();

 

        // Model Factory User

        $otherUsers = \App\Models\User::factory()->count(10)->create();

 

        $users = $otherUsers->concat([$userSatu]);

 

        // Model Factory BlogPost

        \App\Models\BlogPost::factory()->count(5)->make()->each(function ($post) use ($users)

        {

            $post->user_id  = $users->random()->id;

            $post->save();

        });

 

    }

}

 

Jalankan command refresh-seeder.

php artisan migrate:refresh --seed

Silahkan lihat di table blog_posts, ada 20 rows yang sudah terinput.

Membuat Model Factory untuk Comment

Buat Comment model factory dengan menjalankan command di bawah ini. Code di bawah ini akan membuat file database/factories/CommentFactory.php.

php artisan make:factory CommentFactory

Buka file database/factories/CommentFactory.php dan tambahkan code di bawah ini.

<?php

 

namespace Database\Factories;

 

use App\Models\Comments;

use Illuminate\Database\Eloquent\Factories\Factory;

 

class CommentsFactory extends Factory

{

    /**

     * The name of the factory's corresponding model.

     *

     * @var string

     */

    protected $model = Comments::class;

 

    /**

     * Define the model's default state.

     *

     * @return array

     */

    public function definition()

    {

        return [

            "content" => $this->faker->text()

        ];

    }

}

 

Buka file database/seeders/DatabaseSeeder.php, dah ubah menjadi seperti ini.

<?php

 

namespace Database\Seeders;

 

use Illuminate\Database\Seeder;

use Illuminate\Support\Facades\DB;

use Illuminate\Support\Str;

 

class DatabaseSeeder extends Seeder

{

    /**

     * Seed the application's database.

     *

     * @return void

     */

    public function run()

    {

        // DB::table('users')->insert([

        //     'name' => "User 1",

        //     'email' => "user1@mail.com",

        //     'email_verified_at' => now(),

        //     'password' => bcrypt('password'),

        //     'remember_token' => Str::random(10)

        // ]);

 

        // Model Factory UserSatu

        $userSatu = \App\Models\User::factory()->userSatu()->create();

 

        // Model Factory User

        $otherUsers = \App\Models\User::factory()->count(10)->create();

 

        $users = $otherUsers->concat([$userSatu]);

 

        // Model Factory BlogPost

        $posts = \App\Models\BlogPost::factory()->count(20)->make()->each(function ($post) use ($users)

        {

            $post->user_id  = $users->random()->id;

            $post->save();

        });

 

        // Model Factory BlogPost

        $comments = \App\Models\Comments::factory()->count(20)->make()->each(function ($comment) use ($posts)

        {

            $comment->blog_post_id  = $posts->random()->id;

            $comment->save();

        });

 

    }

}

 

 

Silahkan lihat di table comments, ada 20 rows yang sudah terinput atau coba liat pada brows maaka aanda akan melihat beberapa comentar pada blogpost.



 

 

Next Post Previous Post
No Comment
Add Comment
comment url