我的最愛追蹤功能製作

定義資源

我的最愛功能,製作一個可以讓 user 追蹤動物的操作,是一個連結的關係,綁定動物與用戶的關聯。

依照以前的經驗,我會幫這樣的動作取一個名字 like 之類的資料表來儲存內容。

但經過幾次的打造API經驗後,在規劃資料表的命名上,如果系統規模很大只有 like 當表名不是很明確。

我們這個系列打造的送養系統如果想要新增一個追蹤某位愛心媽媽的功能,就會覺得like不是很明確。

這樣在資料庫中看到 like 資料表,無法明確的知道內容。所以這邊我不另外給它一個名字。

會製作一張表  animal_user  這是我目前的原則!可以清楚知道這張資料表紀錄著 animal 與 user 的關係,並且依照字母排列A->Z命名這張表。 所以不命名為 user_animal 這是開始用 Laravel 後才有的習慣,在某個官方文章有寫到預設是 開頭A->Z來建立資料表。

這樣的資料庫設計 叫做 多對多關聯, 用這張中間的資料表紀錄,兩者個關係。可以參考我另外一個系列的鐵人賽介紹關聯式資料庫的關聯模式 文章連結

定義的這個資源物件內容

欄位名 說明 格式 備註
id 分類id int(10) unsigned
animal_id 動物ID bigInteger(10) unsigned
user_id 使用者ID bigInteger(10) unsigned
created_at 新建時間 timestamp NULL
updated_at 更新時間 timestamp NULL

產生基本檔案

C:\project\animal\ > php artisan make:migration create_animal_user_table

設定路由

animal/routes/api.php

// 這裡可以用 like 辨識
Route::post('animal/{animal}/like', 'AnimalController@like');

URI 設計為 animal/1/like 表示該登入的使用者,喜歡id:1的動物,並且指定到  AnimalController 中的 like 方法,這裡選擇寫在 AnimalController  因為操作的流程,都是看到動物再去點選喜歡功能,所以寫在這裡面。

撰寫程式

Migration

animal/database/migrations/2019_09_05_082939_create_animal_user_table.php

<?php

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

class CreateAnimalUserTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('animal_user', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('animal_id')->unsigned()->comment('動物ID');
            $table->bigInteger('user_id')->unsigned()->comment('使用者ID');
            $table->timestamps();
        });

        // Schema::table 訪法來對上面建立好的資料表 新增外鍵約束
        Schema::table('animal_user', function (Blueprint $table) {

            // user_id 外鍵
            $table->foreign('user_id')
                ->references('id')->on('users')
                ->onDelete('cascade');

            // animal_id 外鍵
            $table->foreign('animal_id')
                ->references('id')->on('animals')
                ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('animal_user', function (Blueprint $table) {
            // 刪除外鍵約束 (這個表名_外鍵名_foreign)
            $table->dropForeign('animal_user_user_id_foreign');
            $table->dropForeign('animal_user_animal_id_foreign');
        });

        Schema::dropIfExists('animal_user');
    }
}

Model

animal/app/Animal.php MODEL 新增這兩種方法

/**
* 取得動物的刊登人
*/
public function user()
{
    return $this->belongsTo('App\User');
}

/**
* 多對多關聯animal與user
*/
public function like()
{
    return $this->belongsToMany('App\User')->withTimestamps();
}

animal/app/User.php MODEL 新增這兩種方法

/**
* 取得user 刊登的 animal
*/
public function animal()
{
    return $this->hasMany('App\Animal', 'user_id', 'id');
}

/**
* 多對多關聯animal與user
*/
public function like()
{
    return $this->belongsToMany('App\Animal')->withTimestamps();
}

Controller

animal/app/Http/Controllers/AnimalController.php 新增like方法

use Auth;

/**
    * 動物加入或移除我的最愛
    *
    * @param  \App\Animal  $animal
    * @return \Illuminate\Http\Response
    */
public function like(Animal $animal)
{
    $animal->like()->toggle(Auth::user()->id);

    return response(null, Response::HTTP_NO_CONTENT);
}

測試看看

POST api/like/{animal} <-自行替換要加入我的最愛的動物id

請求設定畫面

確認 token 有附加在Headers 以及 使用 POST 發送請求,網址確認 動物id 已存在 animals 這張資料表內。

按下 Send

加入動物到我的最愛

檢查資料表,出現一筆紀錄表示程式碼正確無誤!

關注一隻動物

我的最愛 移除一隻動物

你已經關注了一隻動物,現在嘗試取消關注看看!在發送一次請求 按下Send

取消關注一隻動物

animal_user 資料表少了一筆資料,目前為空的資料表!

完成了喜歡的功能了!

參考

Laravel 官方文件 Relationships


一則迴響

發佈留言