iT邦幫忙

2024 iThome 鐵人賽

DAY 21
0
Modern Web

後端菜雞仔想學 Laravel系列 第 21

分類 CRUD:指派另一位店長!

  • 分享至 

  • xImage
  •  

需求想像

產品有很多品項,會需要為它們分門別類!
就像你在逛網拍的時候,想找洋裝就去洋裝的類別看,想找上衣就去上衣的類別看,沒什麼想法的時候,還可以點進「最新商品」去逛逛。

所以「分類」這件事也能增加使用者體驗,引導使用者快速找到想要的產品。

「讓消費者可以透過這個網站線上查看產品的相關資訊。」
這是此線上產品瀏覽系統的核心概念,那「分類」這件事就是需要的。

我在 Migration & 資料庫設計 這篇文章時就先規劃好了 types 表。

所以今天就來建立 Type 這個 resource!跟 Product 一樣畫葫蘆的步驟即可。

定義資源

類別 type,為該系統的產品分類,例如:甜點、茶品等等。

資料表規劃:types 表

欄位名 說明 格式 包含備註內容
id ID unsignedBigInteger
name 類別名稱 varchar(255)
sort 排序 integer 預設值100
created_at 新建時間 timestamp
updated_at 更新時間 timestamp

API 規劃

Method URI Name Action
POST api/types/ type.store App\Http\Controllers\TypeController@store
GET api/types/ type.index App\Http\Controllers\TypeController@index
GET api/types/{type} type.show App\Http\Controllers\TypeController@show
PATCH api/types/{type} type.update App\Http\Controllers\TypeController@update
DELETE api/types/{type} type.destroy App\Http\Controllers\TypeController@destroy

建立 Type 的基本檔案

php artisan make:model Type -rmc

建立一個名為 Type 的 Model,並同時「載入預設CRUD方法」建立以下檔案:

  • Migration
  • Controller

「TypeController」就是我指派的另一位店長。

分配店員:設定路由

打開 api.php 將路由指定到 TypeController

use App\Http\Controllers\TypeController;

Route::apiResource('types', TypeController::class);

查看 Route List 是否都有正確對應

php artisan route:list

https://ithelp.ithome.com.tw/upload/images/20241005/20169300z9BbA8Rdea.jpg

小備註:名稱的命名根據 RESTful 設計模式,通常都以「複數」來命名。


Migration

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('types', function (Blueprint $table) {
            $table->id();
            $table->string('name')->unique()->comment('類別名稱');
            $table->integer('sort')->default(100)->comment('排序');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('types');
    }
};

什麼是 default(100)?

表示設定預設值 100,通常有以下作用:

  1. 確保每一筆資料在 sort 欄位都有值,避免因為缺少這個欄位的值而導致資料處理邏輯出錯。
  2. 在插入新資料時,如果沒有指定 sort 值,系統會自動填入預設值 100,這樣開發者就不需要每次插入資料時都手動填寫這個欄位。
  3. 預設值 100 可以作為一個中間值,方便將來進行排序操作,比設定 0 或 1 更有彈性。
  4. 假設通常手動設定的排序值可能是較小的數字(如 1、2、3 等),將預設值設為 100 可以清楚區分出哪些資料是自動填入的,哪些是手動設定的。

執行 Migration

php artisan migrate

各方法邏輯:

index:取得所有類別的資料

回傳所有類別資料,並依照 sort 欄位進行排序。

store:新增一個新的類別

  • 驗證提交的資料。
  • 如果 sort 欄位沒有填寫,自動把它設成目前 sort 欄位的最大值加 1。
  • 驗證通過後即新增類別資料。
  • 如果新增成功,會回傳新增後的類別資料。

show:取得單一類別的資料

回傳特定類別的資料。

update:更新指定的類別資料

  • 使用 PATCH 方法來更新資料,只需要更新有變動的部分即可。
  • 如果更新成功,會回傳更新後的資料和「類別已更新!」的訊息。

destroy:刪除指定的類別資料

  • 刪除資料庫中的特定類別。
  • 如果刪除成功,會回傳「此類別已刪除成功!」的訊息。

設定 TypeController:

<?php

namespace App\Http\Controllers;

use App\Models\Type;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class TypeController extends Controller
{
    // 取得所有類別
    public function index()
    {
        $types = Type::orderBy('sort')->get(); // 依照排序欄位排列
        return response()->json($types, Response::HTTP_OK);
    }

    // 新增類別
    public function store(Request $request)
    {
        $rules = [
            'name' => 'required|max:50|unique:types,name',
            'sort' => 'nullable|integer',
        ];
        // 驗證請求資料
        $validatedData = $request->validate($rules);

        if (empty($validatedData['sort'])) {
            $max = Type::max('sort');
            $validatedData['sort'] = $max + 1;
        }

        $type = Type::create($validatedData);
        return response($type, Response::HTTP_CREATED);
    }

    // 取得單一類別
    public function show(Type $type)
    {
        return response()->json($type, Response::HTTP_OK);
    }

    // 更新類別
    public function update(Request $request, Type $type)
    {
        $rules = [
            'name' => 'nullable|max:50|unique:types,name,' . $type->id,
            'sort' => 'nullable|integer',
        ];
        // 驗證請求資料
        $validatedData = $request->validate($rules);
        // 更新類別資料
        $type->update($validatedData);

        return response()->json([
            'message' => '類別已更新!',
            'data' => $type
        ], Response::HTTP_OK);
    }

    // 刪除類別
    public function destroy(Type $type)
    {
        $type->delete();

        return response()->json([
            'message' => '此類別已刪除成功!'
        ], Response::HTTP_OK);
    }
}


設定 Type.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Type extends Model
{
    use HasFactory;
    
    protected $fillable =[
        'name',
        'sort',
    ];
}

這樣產品分類的 CRUD 都建立完成囉!
明天可以來進行模型關聯,然後再一起使用 Postman 測試看看。


上一篇
orWhere、orderBy:關鍵字搜尋邏輯更新、加入排序機制!
下一篇
hasMany & belongsTo:建立模型關聯
系列文
後端菜雞仔想學 Laravel30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言