Xây dựng website bán hàng bằng Laravel - Thiết lập Danh mục Sản phẩm

TQH 2023-08-30 15:14:40

Danh mục Sản phẩm (Product Category) là một nhóm các sản phẩm tương tự có chung các đặc điểm liên quan. Với việc phân loại sản phẩm theo từng danh mục sẽ giúp khách hàng của bạn có thể nhanh chóng tìm được sản phẩm mong muốn dựa trên các đặc điểm chung của từng dòng sản phẩm.

E-commerce với Laravel là loạt bài ghi lại toàn bộ quá trình xây dựng hệ thống thương mại điện tử được thực hiện bởi Transmoni team nhắm hướng dẫn mọi người làm quen với Laravel, Livewire, Alpine.js và Tailwind CSS. Hiện dự án đang được cập nhật liên tục, toàn bộ mã nguồn của dự án sẽ được công khai miễn phí theo hình thức mã nguồn mở trên trang Github của Transmoni sau khi hoàn tất loạt bài hướng dẫn này.

Chuẩn bị cơ sở dữ liệu

Để tạo file migration phục vụ cho việc tạo bảng danh mục sản phẩm trên cơ sở dữ liệu chúng ta sử dụng lệnh sau:

php artisan make:migration create_categories_table

lúc này chúng ta sẽ có 1 file 2022_02_27_092239_create_categories_table.php trong thư mục database/migrations với nội dung được dựng sẵn như sau:

class CreateCategoriesTable extends Migration
{
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();

            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('categories');
    }
}

tiếp đến hãy điền vào các table mà bạn muốn tạo, hoặc làm theo như của tôi:

class CreateCategoriesTable extends Migration
{
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->foreignIdFor(\App\Models\Category::class, 'parent_id')->nullable()->constrained('categories')->nullOnDelete();
            $table->string('name');
            $table->string('slug')->unique();
            $table->text('description')->nullable();
            $table->timestamps();
        });
    }
    ....
}

trong đó chúng ta sẽ có các bảng (table) như sau:

  • parent_id để chỉ định khóa ngoại (foreign key) cho tính năng danh mục cha và con theo phương pháp đệ quy (recursion).

  • name để đặt tiêu đề cho danh mục

  • slug để đặt đường dẫn uri khi truy cập từng danh mục thay vì sử dụng id

  • description để viết ghi chú cho từng danh mục

tiếp đến chúng ta chạy lệnh migrate để thực hiện thiết lập cơ sở dữ liệu cho danh mục sản phẩm:

php artisan migrate

và kết quả sau khi hoàn tất.

Thiết lập Seeder để tạo các bản ghi mẫu

Sau khi hoàn tất tạo bảng, chúng ta sẽ cần tạo sẵn một số bản ghi phục vụ cho việc in nội dung ra view nhằm thao tác với các nội dung này. Thay vì phải nhập dữ liệu bằng tay một cách thủ công thì Laravel cung cấp cho chúng ta một tính năng có tên gọi là Seeder (dịch nôm na là gieo hạt). Với tính năng này bạn có thể định sẵn các bản ghi mà chúng ta muốn tạo chỉ một lần duy nhất, sau khi nghịch ngợm phá phách với các bản ghi (trên môi trường local thôi nhé) thì chỉ cần chạy lại lệnh db:seed để tái thiết lập các bản ghi như đã khai báo.

php artisan make:seeder CategorySeeder

Chúng ta sẽ sử dụng lệnh trên để tạo file seeder cho danh mục sản phẩm, một file mới sẽ được khởi tạo tại database/seeders/CategorySeeder.php với nội dung dựng sẵn như sau:

<?php

namespace Database\Seeders;

use App\Models\Category;
use Illuminate\Database\Seeder;

class CategorySeeder extends Seeder
{
    public function run()
    {
        //
    }
}

và chúng ta sẽ tiến hành khai báo nội dung các bản ghi như sau:

class CategorySeeder extends Seeder
{
    public function run()
    {
        DB::table('categories')->upsert([
            [
                'name' => 'Women',
                'slug' => 'women',
                'description' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmodtempor',
            ], [
                'name' => 'Men',
                'slug' => 'men',
                'description' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmodtempor',
            ], [
                'name' => 'Kid',
                'slug' => 'kid',
                'description' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmodtempor',
            ], [
                'name' => 'Accessories',
                'slug' => 'accessories',
                'description' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmodtempor',
            ]
        ], 'slug');
    }
}

lưu ý rằng ở đây tôi sử dụng phương thức upsert (ra mắt từ Laravel phiên bản 8.1.0) thay vì insert vì tôi đã xác định sẵn mình cần có 4 danh mục như đã khai báo là Women, Men, Kid và Accessories. Nếu sử dụng insert thì khi cần seed lại các bản ghi trong trường hợp một trong số các bản ghi được khai báo đã tồn tại sẽ phát sinh lỗi trùng lặp do cột slug của chúng ta là độc nhất (unique). Do đó sử dụng upsert và khai báo slug là unique sẽ giúp cho seeder của chúng ta chỉ thực hiện seed lại các bản ghi nếu bị thiếu mà thôi.

Tiếp theo tại file database/seeders/DatabaseSeeder.php chúng ta cần khai báo class CategorySeeder:

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(CategorySeeder::class);
    }
}

cuối cùng chúng ta chạy lệnh db:seed để thực hiện tạo các bản ghi đã khai báo:

php artisan db:seed

và kết quả nhận được như sau:

Ngoài ra bạn cũng có thể sử dụng Factory để tạo các bản ghi mẫu, với sự hỗ trợ của fakerphp có thể giúp cho nội dung bản ghi được sinh ra một cách ngẫu nhiên. Sử dụng lệnh sau để tạo Factory cho danh mục sản phẩm của chúng ta:

php artisan make:factory CategoryFactory

tại file database/factories/CategoryFactory.php bạn bổ sung nội dung cho function difinition như sau:

public function definition(): array
{
    return [
        'name' => $this->faker->text(32),
        'slug' => $this->faker->slug,
        'description' => $this->faker->text(200),
    ];
}

Và thay vì khai báo từng danh mục riêng lẻ như ở trên, tại database/seeders/CategorySeeder.php chúng ta nhập nội dung như sau:

class CategorySeeder extends Seeder
{
    public function run()
    {
          Category::factory(10)->create();
    }
}

Và tiến hành chạy lệnh db:seed để tạo các bản ghi mẫu với nội dung ngẫu nhiên.

Thiết lập model cho danh mục sản phẩm

Ok vậy là chúng ta đã có cơ sở dữ liệu cho danh mục sản phẩm cùng với một số bản ghi mẫu, việc tiếp theo là thiết lập model cho bảng này. Tiến hành sử dụng lệnh make:model để thực hiện:

php artisan make:model Category

một file mới sẽ được tạo tại app/Models/Category.php kế bên model User (có sẵn sau khi cài đặt Laravel) với nội dung dựng sẵn như sau:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    //
}

không có gì nhiều đúng không nào? Hiện tại chúng ta chưa có nhiều tính năng liên quan đến phần danh mục này ngoài việc sử dụng slug để làm URI cho phần truy cập, do đó chúng ta chỉ cần khai báo như sau:

class Category extends Model
{
    public function getRouteKeyName(): string
    {
        return 'slug';
    }
}

Kết luận

Vậy là chúng ta đã hoàn tất việc chuẩn bị cơ sở dữ liệu cho danh mục sản phẩm và thiết lập một Eloquent Model để quản lý bảng này. Xin lưu ý rằng trình tự thực hiện trong bài này không hoàn toàn bắt buộc, bạn có thể sử dụng duy nhất một dòng lệnh để có thể tạo cùng lúc model và migration như sau:

php artisan make:model Category --migration --seed

và Laravel sẽ tự động thực hiện toàn bộ quy trình cho chúng ta. Bạn có thể xem thêm tại Generating Model Classes.

Ở bài tiếp theo chúng ta sẽ thực hiện thiết lập Livewire component để xây dựng tính năng quản lý danh mục sản phẩm cho Admin bao gồm thêm mới, chỉnh sửa hay xóa bỏ các bản ghi.

Hẹn gặp lại các bạn!