分類CRUD、模型關聯

定義資源

類別 type,預計紀錄該系統的動物分類 (貓、狗、其他…)

定義這個資源物件的內容

定義一個資源需要有哪些詳細資料。

欄位名 說明 格式 備註
id 分類id int(10) unsigned
name 類別名稱 varchar(50)
sort 排序 int(10) 
created_at 新建時間 timestamp NULL
updated_at 更新時間 timestamp NULL

產生基本檔案

C:\project\animal\ > php artisan make:model Type -rmc

設定路由

來到 api.php 把路由指定到 TypeController

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

寫程式時間

Migration

animal/database/migrations/2019_08_30_213108_create_types_table.php 檔名的時間會是你產生檔案時的時間

<?php

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

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

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

資料庫外鍵約束關聯的部分會再後面優化的時候加入!

Controller

TypeController

<?php

namespace App\Http\Controllers;

use App\Type;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class TypeController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $types = Type::get();
        return response($types, Response::HTTP_OK);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|max:50|unique:types,name',
            'sort' => 'nullable|integer',
        ]);

        if (empty($request->sort)) {
            $max = Type::get()->max('sort');
            $request['sort'] = $max+1;
        }

        $type = Type::create($request->all());
        return response($type, Response::HTTP_CREATED);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Type  $type
     * @return \Illuminate\Http\Response
     */
    public function show(Type $type)
    {
        return response($type, Response::HTTP_OK);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Type  $type
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Type $type)
    {
        $type->update($request->all());
        return response($type, Response::HTTP_OK);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Type  $type
     * @return \Illuminate\Http\Response
     */
    public function destroy(Type $type)
    {
        $type->delete();
        return response(null, Response::HTTP_NO_CONTENT);
    }
}

Model

雖然我們在資料庫的部分,沒有做關聯,但在撰寫Model時可以先建立好模型關聯。方便用簡潔的方式取的關聯資料。例如:

查詢「狗」種類中的所有動物 (假設狗的類別 ID 是 1 )

$animals = Type::find('1')->animals;

或者反過來查詢這個動物是什麼種類。(如下語法可以讀取動物同時並帶出關聯類別)

$animal = Animal::with('type')->find('1');

很常聽到的 MVC架構 , M 就是Model,每個資料表都有一個對應的Model用來與該資料表互動。

Model有點像中間人的概念,只要告訴Model這個人就能新增、刪除、修改、查詢資料表。

Laravel 的Eloquent ORM 提供簡潔的 Active Record 模式來實作與資料庫的互動。

Active Record

特點就是剛剛所說的一個 Model 對應關聯型資料庫中的一個表,而 Model 的一個實體對應資料表中的一行記錄。

物件關聯映射 ORM

可以輕鬆儲存物件的特性與關係,取出來的時候也不需要撰寫 SQL 語句,總體上減少了與資料庫存取有關的程式碼。

animal/app/Type.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Type extends Model
{
    /**
     * 可以被批量賦值的屬性。
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'sort'
    ];
    /**
     * 取得類別的動物
     */
    public function animals()
    {
        return $this->hasMany('App\Animal', 'type_id', 'id');
    }
}

Animal 的 Model 也要加上反向的關聯,這樣就可以從Animal這個方向去查詢type,主要是下方的 type 方法

animal/app/Animal.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Animal extends Model
{
    /**
     * 可以被批量賦值的屬性。
     *
     * @var array
     */
    protected $fillable = [
        'type_id',
        'name',
        'birthday',
        'area',
        'fix',
        'description',
        'personality',
    ];

    /**
     * 取得動物的分類
     */
    public function type()
    {
        return $this->belongsTo('App\Type');
    }
}

測試之前記得先跑 php artisan migrate指令。

資料庫讓它新建 types 資料表。

嘗試讓他們回傳下面結果

新建類別

查詢所有類別

查詢一筆類別

刪除一筆類別

相同URI再送一次刪除請求

注意以上狀態碼,以及回傳的內容,如果有錯誤嘗試看看哪裡有打錯字或是少引入檔案,上面的程式碼也是我不斷地發生錯誤訊息,修正後才完成的!加油~


發佈留言