定義資源
我的最愛功能,製作一個可以讓 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
資料表少了一筆資料,目前為空的資料表!
完成了喜歡的功能了!
斜槓媽媽
2019-10-29謝謝你無私的分享! 我真希望我也看得懂
Victor
2019-12-26感謝妳的回覆 ^^ 如果有疑問的地方歡迎跟我討論!