iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 19
2
Modern Web

使用 Laravel 打造 RESTful API系列 第 19

修改資料表新建 migration

此篇文章同步發於個人部落格

明天我們要來建立權限的部分,之前設定的是驗證使用者的 token 身份驗證,但一般的網站至少會有管理員或一般會員的區分,因此今天先來修改基本需要設定的東西。

變更資料表

資料表原本規劃時沒注意到的地方,或是規劃好的東西難免都會被要求修改需求,所以修改資料表也是一門學問,用 migration 檔案修改檔案可以方便的讓整個團隊更新到最新的版本。

跟大家說一個經驗,如果目前的系統是在線上用運行中的,並且公司沒有 DBA 在負責管理資料庫的話,要變更資料庫欄位時一定要三思而後行,至少要確認有沒有備份。

有時候可能會覺得線上直接改資料表比較快,但是如果只有在線上改,可能其他共同開發者會不知道該怎麼修改,要設定什麼樣的欄位名稱,什麼樣的資料類型(整數、字串...)

因此可以建立一個新的 migration 因為它包含在 git 的範圍中,只要提交 git 後,其他夥伴 git pull 就會有這個新的檔案,不建議在原來的 migration 修改。

例如要改 animals 資料表,不要直接去修改之前產生 animal 的 migration 檔案,共同開發的夥伴會無法下 php artisan migrate 指令,假使夥伴已經運行過migration,已經執行過了之前的那個 animal migration 檔案,會起不了作用。

除非,是一個新的專案開始製作,我是覺得可以整理一下 migration 這些檔案 然後直接 php artisan migrate:refresh 直到專案上線。

請產生一個新的 migration 檔案

animals 資料表 新增 user_id 欄位

新增 user_id 用於判斷,是哪一位會員刊登的動物資料,關聯是資料表的運中可以參考我另外一系列資料庫鐵人賽的文章了解什麼是關聯是資料庫

php artisan make:migration add_user_id_to_animals --table="animals"

animal/database/migrations/2019_09_04_234303_add_user_id_to_animals.php

<?php

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

class AddUserIdToAnimals extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('animals', function (Blueprint $table) {
            // 增加 user_id 欄位 (這裡要注意 先把這個欄位設定為 users 資料表中的任一個已存在的會員id )
            $table->bigInteger('user_id')->unsigned()->default(1)->comment('使用者ID');

            // 新增外鍵約束 如果user id:1 刪除 animal user_id = 1 也會全部刪除
            $table->foreign('user_id')
                ->references('id')->on('users')
                ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {

        Schema::table('animals', function (Blueprint $table) {
            // 刪除外鍵約束 (這個表名_外鍵名_foreign)
            $table->dropForeign('animals_user_id_foreign');

            //刪除user_id 欄位
            $table->dropColumn('user_id');
        });

    }
}

完成後並執行以下指令

php artisan migrate

在看 animals 資料表多一個user_id 欄位。

預設值設為使用者資料表的id 是因為資料表中目前有 id為1的會員,照理來說,這樣是錯誤的設定,但因為們目前 animals 資料表裡面已經有動物的資料了!如果直接新增欄位 它會先填入值0 ,由於我們又要新建外鍵約束,所以 user_id 對應不到 users 資料表中的 id 會無法運行成功!

users 資料表 新增 permission 欄位

新增一個欄位用於判斷管理員或是其他身份的會員。

<?php

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

class AddPermissionToUsers extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            //使用 permission 來記錄是不是管理員或其他類別
            $table->string('permission')->comment('帳號權限');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            //刪除 permission 欄位
            $table->dropColumn('permission');
        });
    }
}

下指令

php artisan migrate

users 資料表就會多一個 permission 欄位,我使用 Mysql 如果用 其他資料庫,好像會出現錯誤,因為原本資料庫裡面已經有一筆會員資料,上面 up 方法中新建的欄位,permission 不允許空值的所以可能沒辦法新增,若有遇到問題可以從這方面去想辦法排除。

補充 migrate 撰寫資料表外鍵約束

新建資料庫的外鍵約束可以確保資料庫的資料正確性。例如:會員的資料刪除了!動物如果還對應到刪除的會員,後端程式可能會出錯。

up 方法中

新建資料表可能自動產生的 方法是 Schema::create() 把新建外鍵約束的程式寫在裡面會出錯,所以建議建好資料表以後方法外再寫一個 Schema::table() 對資料表修改。

down 方法中

小技巧 請先刪除外鍵關係,然後刪除資料表,如上方 2019_09_04_234303_add_user_id_to_animals 檔案的dow方法。

不知道外鍵是什麼名稱?

可以開啟你的資料庫圖形介面程式,我是使用Sequel Pro,選擇資料表 點選 Relations(關係)。

外鍵查詢


上一篇
OAuth2 認證機制 Token 原理
下一篇
會員權限設計(管理員、一般會員)
系列文
使用 Laravel 打造 RESTful API30

尚未有邦友留言

立即登入留言