[laravel series] 4. Build blog - Thiết kế database, seed dữ liệu mẫu
Tiếp tục laravel resies, bài này mình sẽ bắt đầu build các tính năng của một trang blog, qua đó chúng ta có thể học được cách thiết kế database, áp dụng các tính năng của laravel để build các tính năng liên quan. Thực hành chính là cách học nhanh nhất :). Bài này chúng ta sẽ tập trung vào phần thiết kế database, các bảng dữ liệu, quan hệ giữa các bảng.
Link project ở đây mọi người tham khảo thêm ở đây nhé, trong quá trình viết bài có thể có thiếu xót. phuongdm1987/laravel-tutorial (github.com)
Trong bài [Laravel series] 2. Cài đặt môi trường local chúng ta đã tạo database laravel_tutorial, bây giờ chúng ta sẽ tạo các bảng trong database này.
- Tạo migrate cho bảng
categories
docker/run artisan make:migration create_categories_table- Update function up trong file migrate vừa tạo như bên dưới:
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->foreignId('parent_id')->default(0)->index();
$table->string('name');
$table->string('slug')->unique();
$table->timestamps();
});
- Tạo migrate cho bảng
posts
docker/run artisan make:migration create_posts_table- Update function up trong file migrate vừa tạo như bên dưới:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('author_id')->index();
$table->foreignId('category_id')->default(0)->index();
$table->string('title');
$table->string('slug')->unique();
$table->text('summary');
$table->text('content');
$table->enum('status', ['DRAFT', 'PUBLISHED'])->default('DRAFT')->index();
$table->softDeletes();
$table->timestamps();
});
- Tạo migrate cho bảng
comments
docker/run artisan make:migration create_comments_table- Update function up trong file migrate vừa tạo như bên dưới:
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->index();
$table->foreignId('post_id')->index();
$table->foreignId('parent_id')->default(0)->index();
$table->text('content');
$table->timestamps();
});
- Tạo migrate cho bảng
tags
docker/run artisan make:migration create_tags_table- Update function up trong file migrate vừa tạo như bên dưới:
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
});
- Tạo migrate cho bảng
post_tag
docker/run artisan make:migration create_post_tag_table- Update function up trong file migrate vừa tạo như bên dưới:
Schema::create('post_tag', function (Blueprint $table) {
$table->foreignId('post_id');
$table->foreignId('tag_id');
$table->primary(['post_id', 'tag_id']);
});
Chúng ta chạy lệnh docker/run artisan migrate để tạo các bảng phía trên.
Tiếp theo chúng ta sẽ tạo model, factory, và seeder để tạo dữ liệu mẫu cho các đối tượng: category, post, comment, tag
Các câu lệnh tạo model, factory, và seeder
docker/run artisan make:model ten_modeldocker/run artisan make:factory ten_factorydocker/run artisan make:seeder ten_seeder
Mình sẽ tạo model và factory với đường dẫn là tên model, trước tiên chúng ta chuyển model User từ /model/User.php thành /model/User/User.php mục đích để sau này chung ta thêm các file liên quan đến model vào cùng một thư mục, để dễ quản lý hơn.
Tương tự chuyển /database/factories/UserFactory thành /database/factories/User/UserFactory
- Tạo model, factory, seeder cho
categorydocker/run artisan make:model Category/Categorydocker/run artisan make:factory Category/CategoryFactorydocker/run artisan make:seeder CategorySeeder
Ở function definition trong file /database/factories/Category/CategoryFactory chúng ta update như sau:
$name = $this->faker->unique()->name;
$slug = Str::snake($name);
return [
'name' => $name,
'slug' => Str::lower($slug),
];
Ở function run trong file /database/seeders/CategorySeeder chúng ta update như sau:
$data = [
[
'name' => 'News General',
'slug' => 'news-general',
],
[
'name' => 'Technology - Hi Tech',
'slug' => 'technology-hi-tech',
],
[
'name' => 'Health',
'slug' => 'health',
],
[
'name' => 'Fashion',
'slug' => 'fashion',
],
[
'name' => 'Sport',
'slug' => 'sport',
],
[
'name' => 'Culture & Education',
'slug' => 'culture-&-education',
],
[
'name' => 'Automotive & Vehicles',
'slug' => 'automotive-&-vehicles',
],
];
$categories = Category::factory()->createMany($data);
$tags = Tag::factory()->count(10)->create();
$posts = collect();
for ($i = 1; $i <= 10; $i++) {
$post = Post::factory()->create([
'category_id' => $categories->random()->id,
]);
$posts->add($post);
}
foreach ($posts as $post) {
$post->tags()->sync([
'tag_id' => $tags->random()->id,
]);
}
$comments = collect();
for ($i = 1; $i <= 10; $i++) {
$comment = Comment::factory()->create([
'post_id' => $posts->random()->id,
]);
$comments->add($comment);
}
foreach ($comments as $comment) {
Comment::factory([
'parent_id' => $comment->id,
'post_id' => $comment->post_id,
])
->count(2)
->create();
}
- Tạo model, factory, seeder cho
postdocker/run artisan make:model Post/Postdocker/run artisan make:factory Post/PostFactory
Ở function definition trong file /database/factories/Post/PostFactory chúng ta update như sau:
$title = $this->faker->unique()->name;
$slug = Str::snake($title);
$status = Arr::random([
'DRAFT',
'PUBLISHED',
]);
return [
'author_id' => 1,
'category_id' => random_int(1, 7), // 7 category in CategorySeeder
'title' => $title,
'slug' => Str::lower($slug),
'summary' => $this->faker->paragraph,
'content' => $this->faker->realText(),
'status' => $status,
];
- Tạo model, factory, seeder cho
commentdocker/run artisan make:model Comment/Commentdocker/run artisan make:factory Comment/CommentFactory
Ở function definition trong file /database/factories/Comment/CommentFactory chúng ta update như sau:
return [
'user_id' => 1,
'post_id' => random_int(1, 10),
'content' => $this->faker->realText(),
];
- Tạo model, factory, seeder cho
tagdocker/run artisan make:model Tag/Tagdocker/run artisan make:factory Tag/TagFactory
Ở function definition trong file /database/factories/Tag/TagFactory chúng ta update như sau:
$name = $this->faker->unique()->name;
$slug = Str::snake($name);
return [
'name' => $name,
'slug' => Str::lower($slug),
];
- Update function
runtrong file/database/seeders/DatabaseSeeder.php
User::factory([
'email' => 'henry@gmail.com',
])->create();
$this->call([
CategorySeeder::class,
]);
Chạy lệnh docker/run artisan db:seed để seed dữ liệu mẫu, lệnh này sẽ gọi đến file /database/seeders/DatabaseSeeder.php để seed data.
Vậy là chúng ta đã hoàn tất quá trình tạo bảng và thêm dữ liệu mẫu. Về các bảng dữ liệu mình tạo các field đơn giản có thể chưa đầy đủ, trong quá trình chúng ta trinh phục project blog này, có thể sẽ có các cập nhật về cấu trúc database để tiến hoá hơn. Các bạn cùng theo dõi trong các phần sau nhé, thanks.
Mọi thắc mắc, góp ý, mọi người cứ mạnh dạn comment ở dưới bài giúp mình. Mình sẽ có gắng phản hồi sớm nhất có thể :).

Nhận xét
Đăng nhận xét