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(5, true)
];
}
}
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.